001: package com.sun.portal.proxylet.client.common.browser;
002:
003: import com.sun.portal.proxylet.client.common.Param;
004: import com.sun.portal.proxylet.client.common.StringUtil;
005: import com.sun.portal.proxylet.client.common.Log;
006: import com.sun.portal.proxylet.client.common.ui.ProxyletUI;
007:
008: import java.io.*;
009: import java.net.*;
010: import java.util.Vector;
011: import java.util.StringTokenizer;
012: import java.util.PropertyResourceBundle;
013: import java.awt.*;
014:
015: import javax.swing.*;
016:
017: public class BrowserHelper {
018:
019: /**
020: * parsePACFile
021: * This function is responsible for extracting
022: * proxy server and port for gateway address
023: * from the PAC file.
024: */
025: public static void parsePacFile(String autoConfigURL) {
026: String pacFileBody;
027: String contentType;
028: boolean redirect = false;
029: InputStream autoConfigURLInputStream = null;
030: URLConnection conn = null;
031:
032: try {
033:
034: // Loop atleast one time till we get the actual PAC URL
035: do {
036: redirect = false;
037: //
038: // autoConfigURL could point to a script on the local machine
039: // or could reside on a webserver
040: //
041: URL configURL = new URL(
042: getFormatedAutoConfigURL(autoConfigURL));
043: conn = configURL.openConnection();
044: if (autoConfigURL.trim().startsWith("http")) {
045: // Some additional processing in case of a URL.
046: // Set cache to false, because we want the browser to
047: // do some work for us.
048: //
049: conn.setUseCaches(false);
050: conn.setDoInput(true);
051: conn.setAllowUserInteraction(false);
052: contentType = conn.getContentType();
053: autoConfigURLInputStream = conn.getInputStream();
054: } else {
055: contentType = "file";
056: }
057:
058: if (contentType
059: .equalsIgnoreCase("application/x-internet-signup")
060: || autoConfigURL.trim().toUpperCase().endsWith(
061: ".INS")) {
062: PropertyResourceBundle insRes = null;
063: String autoConfigJS = null;
064: try {
065: DataInputStream in = new DataInputStream(
066: autoConfigURLInputStream);
067: insRes = new PropertyResourceBundle(in);
068: //
069: // AutoConfigJSURL in the .INS file would point to the PAC file
070: //
071: autoConfigJS = insRes
072: .getString("AutoConfigJSURL");
073: } catch (Exception ex) {
074: ex.printStackTrace();
075: }
076:
077: //
078: // If AutoConfigJSURL is present in INS file,
079: // we would need to get a stream to the PAC file.
080: // So we go into the loop
081: // again with autoConfigJS as the new URL
082: //
083: if (autoConfigJS != null
084: && (!autoConfigJS.trim().equals(""))) {
085: autoConfigURL = autoConfigJS;
086: redirect = true;
087: } else {
088: // if AutoConfigJSURL is not configured
089: // Check for AutoConfigURL which would point to a .INS file again
090: String redirectAutoConfigURL = null;
091: try {
092: redirectAutoConfigURL = insRes
093: .getString("AutoConfigURL");
094: } catch (Exception ex) {
095: ex.printStackTrace();
096: }
097:
098: if (redirectAutoConfigURL != null
099: && (!redirectAutoConfigURL.trim()
100: .equals(""))) {
101: if (!redirectAutoConfigURL.trim()
102: .equalsIgnoreCase(
103: autoConfigURL.trim())) {
104: // This is really a different INS file name..So go again into the loop
105: autoConfigURL = redirectAutoConfigURL;
106: redirect = true;
107: } else
108: return;
109: } else
110: return;
111: }
112:
113: }
114: } while (redirect);
115:
116: //
117: // Read the PAC URL and get the content
118: //
119: autoConfigURLInputStream = conn.getInputStream();
120: DataInputStream in = new DataInputStream(
121: autoConfigURLInputStream);
122:
123: byte data[] = null;
124: byte buf[] = new byte[128];
125: ByteArrayOutputStream baos = new ByteArrayOutputStream();
126: DataOutputStream dos = new DataOutputStream(baos);
127: int numberOfBytes = 1;
128: while (numberOfBytes > 0) {
129: try {
130: numberOfBytes = in.read(buf);
131: if (numberOfBytes > 0) {
132: dos.write(buf, 0, numberOfBytes);
133: }
134: } catch (IOException ioe) {
135: numberOfBytes = 0;
136: }
137: }
138:
139: try {
140: dos.flush();
141: data = baos.toByteArray();
142: in.close();
143: dos.close();
144: } catch (Exception ex) {
145: ex.printStackTrace();
146: }
147:
148: pacFileBody = new String(data);
149: Param.setClientPACContent(pacFileBody);
150: extractProxyServerFromPAC(pacFileBody);
151: } catch (Exception ex) {
152: ex.printStackTrace();
153: }
154:
155: } // function parsePacFile
156:
157: static void extractProxyServerFromPAC(String pacFileBody)
158: throws Exception {
159: pacFileBody = URLEncoder.encode(pacFileBody);
160: Log.debugu(Param.getString("pinfo.12",
161: "Reading PAC file contents"));
162: Log.debug(pacFileBody);
163: Log.debugu(Param.getString("pinfo.13", "Connecting to server ")
164: + Param.getServletURL());
165:
166: //
167: // Send the PAC file to proxylet servlet
168: //
169: String clientIP = "255.255.255.255";
170: try {
171: clientIP = InetAddress.getLocalHost().getHostAddress();
172: } catch (Exception e) {
173: }
174:
175: String qString = "?command=parsePacFile" + "&clientIP="
176: + clientIP + "&serverURL=" + Param.getGatewayURL();
177:
178: //
179: // Data is of the form PacfileBody=...&ServerURL=gatewayAddress&
180: // clientAddress=address of client
181: // PAC file body => servlet would execute the FileProxyURl function
182: // with serverURl and client address as parameters
183: //
184:
185: String pacdata = "PacFileBody=" + pacFileBody;
186: byte[] result = Param.sendMsgtoServlet(qString, false, true,
187: pacdata.getBytes());
188:
189: String line = null;
190: if (result != null)
191: line = new String(result);
192:
193: line = (line != null) ? line.trim() : null;
194: parseResult(line);
195:
196: }
197:
198: /**
199: * This function parses the response from the server and stores it in Param
200: *
201: * If the result string is null, we set the proxy host to DIRECT ( no proxy )
202: * or The result can contain any number of the following build blocks, seperated by a ;
203: *
204: * PROXY host:port
205: * DIRECT
206: * SOCKS host:port
207: *
208: * The SOCKS block would be igored.
209: * If only one block is present, we call the Param setClientProxyHost
210: * and port.
211: * If multiple blocks are present, we split the blocks and call the Param
212: * set proxy list function
213: */
214: public static void parseResult(String proxyList) {
215: if (proxyList == null || proxyList.equalsIgnoreCase("null")) {
216: Param.setClientProxyInfo("DIRECT", null);
217: return;
218: }
219:
220: //
221: // if proxy starts with Direct, we ignore all other settings. Atleast, this is how
222: // the browser ( IE ) behaves
223: //
224: if (proxyList.startsWith("DIRECT")) {
225: ProxyletUI.setText(Param.getString("pinfo.14",
226: "Using Direct Connection "));
227: Param.setClientProxyInfo("DIRECT", null);
228: return;
229: }
230:
231: StringTokenizer block = new StringTokenizer(proxyList, ";");
232: Vector temp = new Vector();
233: String host = "", port = "-1";
234: String proxyLine = null;
235: while (block.hasMoreTokens()) {
236: host = "";
237: port = "-1";
238: proxyLine = (String) block.nextElement();
239: if (proxyLine.startsWith("PROXY")) {
240: int delim = proxyLine.indexOf(":");
241: if (delim != -1) {
242: host = proxyLine.substring(
243: proxyLine.indexOf(" ") + 1, delim);
244: port = proxyLine.substring(delim + 1, proxyLine
245: .length());
246: } else
247: host = proxyLine.substring(0, proxyLine.length());
248:
249: temp.add(host + ":" + port);
250: }
251: }
252:
253: if (temp.size() == 1) {
254:
255: // Set Param client host and port directly.
256: // This way we can avoid some validations later
257: proxyLine = (String) temp.get(0);
258:
259: Log.debug("Server returned a single proxyline "
260: + proxyLine);
261: ProxyletUI.setText(Param.getString("pinfo.15",
262: "Using Proxy ")
263: + proxyLine);
264:
265: host = proxyLine.substring(0,
266: proxyLine.indexOf(":") != -1 ? proxyLine
267: .indexOf(":") : proxyLine.length());
268: port = "-1";
269:
270: if (proxyLine.indexOf(":") != -1)
271: port = proxyLine.substring(proxyLine.indexOf(":") + 1,
272: proxyLine.length());
273:
274: Param.setClientProxy(host, port);
275: } else {
276: //
277: // Set the Param client proxy list
278: //
279: Param.setClientProxyList(temp);
280:
281: }
282:
283: }
284:
285: public static boolean validateProxy() {
286: return true;
287: }
288:
289: /**
290: * This function generates PAC file content dynamically.
291: */
292: public static void generatePacContent(int port) {
293: String clientPacFileBlock = null;
294: StringBuffer pacContent = new StringBuffer();
295:
296: // Start of PAC file function
297: pacContent
298: .append("function FindProxyForURL(url, host) {\n ");
299:
300: // Check if paccontent blob is specified by the administrator
301: // If the entire pac blob is provided by the administrator, we ignore the rules field
302: if (Param.getPacfileContent() != null) {
303: pacContent.append("var hostb = \"\";\n");
304: pacContent
305: .append(" hostb = FindProxyForURL_server(url, host);\n");
306: pacContent
307: .append(" if (typeof hostb == \"undefined\") ");
308:
309: if (Param.getProxyMethod().equals("MANUAL")) {
310: pacContent.append(" {");
311: }
312: // Generate PAC content based on user's browser configuration
313: // Determine if user had configured a PAC file
314: clientPacFileBlock = Param.getClientPACContent();
315: pacContent
316: .append(generateClientPacBlock(clientPacFileBlock != null));
317:
318: if (Param.getProxyMethod().equals("MANUAL")) {
319: pacContent.append(" }");
320: }
321:
322: pacContent.append(" else {\n");
323: pacContent.append(" return hostb;\n");
324: pacContent.append(" }\n");
325:
326: } else {
327: // Generate PAC content based on Proxylet Rules
328: pacContent.append(generateGatewayPacBlock(port));
329:
330: // Generate PAC content based on user's browser configuration
331: // Determine if user had configured a PAC file
332: clientPacFileBlock = Param.getClientPACContent();
333: pacContent
334: .append(generateClientPacBlock(clientPacFileBlock != null));
335:
336: }
337:
338: pacContent.append("}\n"); //close of the function
339:
340: if (clientPacFileBlock != null) {
341: pacContent.append("\n\n");
342: // Modify the existing function 'FindProxyForURL' to 'FindProxyForURL_client'
343: // in the Pac file body and append the function to pac content.
344: clientPacFileBlock = StringUtil.replaceFirst(
345: clientPacFileBlock, "FindProxyForURL",
346: "FindProxyForURL_client");
347: pacContent.append(clientPacFileBlock);
348: }
349:
350: // Modify the existing func name FindProxyForURL to FindProxyForURL_server
351: // in the pac content
352: if (Param.getPacfileContent() != null) {
353: String pacBody = new String(Param.getPacfileContent());
354: pacBody = StringUtil.replaceFirst(pacBody,
355: "FindProxyForURL", "FindProxyForURL_server");
356: pacBody = StringUtil.replaceAll(pacBody, "useproxy", Param
357: .getClientProxyHost());
358: pacBody = StringUtil.replaceAll(pacBody, "useproxyport",
359: new Integer(Param.getClientProxyPort()).toString());
360: pacBody = StringUtil.replaceAll(pacBody, "proxylethost",
361: Param.getBindIP());
362: pacBody = StringUtil.replaceAll(pacBody, "proxyletport",
363: new Integer(Param.getBindPort()).toString());
364: pacContent.append("\n\n");
365: pacContent.append(pacBody);
366: }
367:
368: // Persist the generated PAC content
369: Param.setNewPACContent(pacContent.toString());
370: }
371:
372: /**
373: * This function generates the pacfile block for gateway
374: * @return string Returns generated gateway pacfile block
375: *
376: */
377: private static String generateGatewayPacBlock(int port) {
378: System.out.println("inside generateGatewayPacBlock");
379: StringBuffer condition = new StringBuffer();
380: condition.append(getRuleSet());
381: return condition.toString();
382: }
383:
384: /**
385: * This function generates the pacfile block(s) based on the client settings
386: * @return string Returns generated client pacfile block(s)
387: *
388: */
389: private static String generateClientPacBlock(boolean existClientPac) {
390: StringBuffer condition = new StringBuffer();
391: if (existClientPac) {
392: condition.append("{\n");
393: condition
394: .append(" var hosta= FindProxyForURL_client(url, host);\n");
395: condition.append(" return hosta;\n");
396: condition.append(" }\n");
397: } else {
398: if (Param.getProxyMethod().equals("MANUAL")) {
399: condition.append(codeManualProxyInfo());
400: }
401: condition.append("{\n");
402: condition.append(" return \"DIRECT\";\n");
403: condition.append(" }\n");
404: }
405:
406: return condition.toString();
407: }
408:
409: /**
410: * This function returns conditional block(s) for manual settings of
411: * proxy. It checks for all the protocols:
412: * http/https/ftp/gopher to generate the pac file for manual settings
413: * @return string Returns conditional blocks
414: *
415: */
416: private static String codeManualProxyInfo() {
417: StringBuffer conditions = new StringBuffer();
418: if (Param.getClientProxyHostHTTP() != null) {
419: conditions.append(getManualCondition("http", Param
420: .getClientProxyHostHTTP(), Param
421: .getClientProxyPortHTTP()));
422: }
423:
424: if (Param.getClientProxyHostFTP() != null) {
425: conditions.append(getManualCondition("ftp", Param
426: .getClientProxyHostFTP(), Param
427: .getClientProxyPortFTP()));
428: }
429:
430: if (Param.getClientProxyHostGopher() != null) {
431: conditions.append(getManualCondition("gopher", Param
432: .getClientProxyHostGopher(), Param
433: .getClientProxyPortGopher()));
434: }
435:
436: if (Param.getClientProxyHostSSL() != null) {
437: conditions.append(getManualCondition("https", Param
438: .getClientProxyHostSSL(), Param
439: .getClientProxyPortSSL()));
440: }
441:
442: return conditions.toString();
443: }
444:
445: /**
446: * autoConfigURLSetting
447: * This function is responsible for extracting the
448: * proxy host and port values from PAC file.
449: * @return boolean Returns false is autoConfigURL configuration is
450: * not set or if the configured proxy server
451: * information is incorrect.
452: *
453: */
454: public static boolean checkPACFileSetting(String autoConfigURL) {
455: if (autoConfigURL == null)
456: return false;
457:
458: BrowserHelper.parsePacFile(autoConfigURL);
459:
460: Param.setProxyMethod("PAC");
461: // Check if the extracted proxyhost and port are valid
462: return BrowserHelper.validateProxy();
463: }
464:
465: /**
466: * This function returns a conditional block for given protocol, domain(s), ip, port
467: * @return string Returns conditional block
468: *
469: */
470: private static String getPacRule(String protocol, String domains,
471: String ip, String port) {
472: StringBuffer condition = new StringBuffer();
473: condition.append("if (");
474:
475: // loop through the domain list seperated with ',' as the delimiter
476: String[] domain = domains.split("\\,");
477: String host = null, iport = null, url = null;
478:
479: for (int i = 0; i < domain.length; i++) {
480: // look for URL string
481: if (domain[i].indexOf("/") != -1) {
482: host = domain[i].substring(0, domain[i].indexOf("/"));
483: url = domain[i].substring(domain[i].indexOf("/") + 1,
484: domain[i].length());
485: } else {
486: host = domain[i];
487: }
488:
489: // look for port
490: int npos = host.indexOf("#");
491:
492: if (npos != -1) {
493:
494: iport = host.substring(npos + 1, host.length());
495: host = host.substring(0, npos);
496: }
497:
498: condition.append("dnsDomainIs(host, ");
499:
500: //String result = "*" + host + ((iport != null)?(":" + iport):"" ) + ((url != null)?("/"+ url + "/*"):"*") ;
501:
502: if (!(host.trim().startsWith(".")))
503: host = "." + host;
504:
505: condition.append("\"" + host + "\") || ");
506:
507: /*if( protocol != null && protocol.equals("*") )
508: condition.append("\"" + result + "\") || ");
509: else
510: condition.append("\"" + protocol + "://"+ result + "\") || ");*/
511:
512: /*if( url != null){
513: result = "*" + host + ((iport != null)?(":" + iport):"" ) + ((url != null)?("/"+ url ):"" );
514:
515: condition.append("shExpMatch(url, ");
516:
517: if( protocol != null && protocol.equals("*") )
518: condition.append("\"" + result + "\") || ");
519: else
520: condition.append("\"" + protocol + "://"+ result + "\") || ");
521: }*/
522:
523: }
524: // strip of the final ||
525: condition = condition.delete(condition.length() - 3, condition
526: .length());
527: condition.append(") {\n");
528:
529: // body of the If condition
530: // If the rule is configured as 'useproxy', use browser's proxy settings.
531: // If the rule is configured as 'direct' (use no proxy setting), return DIRECT
532: //
533: if (ip != null && ip.equals("DIRECT"))
534: condition.append(" return \"DIRECT\"; \n");
535: else if (ip.equals("useproxy")) {
536: if (Param.getClientProxyHost() != null)
537: condition.append(" return \"PROXY "
538: + Param.getClientProxyHost() + ":"
539: + Param.getClientProxyPort() + "\";\n");
540: else
541: condition.append(" return \"DIRECT\"; \n");
542: } else if (ip.equals("proxylethost")) {
543: condition.append(" return \"PROXY "
544: + Param.getBindIP() + ":" + Param.getBindPort()
545: + "\";\n");
546: } else
547: condition.append(" return \"PROXY " + ip + ":"
548: + port + "\";\n");
549:
550: condition.append(" } else ");
551: return condition.toString();
552: }
553:
554: /**
555: * This function returns conditional block(s) for customized rules of
556: * proxylet in pac file.
557: * It expects the rule string to have this format:
558: * protocol:domain1,domain2:IP1:port1|protocol:domain3:IP1:port1 ...
559: * Note: If the input doesn't follow the format of protocol:domain:ip:port
560: * or domain:ip:port then that rule will be ignored.
561: * @return string Returns conditional blocks
562: *
563: */
564: private static String getRuleSet() {
565: String rules = Param.getRules();
566: String[] rule = rules.split("\\|");
567: StringBuffer ruleConditions = new StringBuffer();
568:
569: for (int i = 0; i < rule.length; i++) {
570: String[] ruleValues = rule[i].split("\\:");
571:
572: if (ruleValues.length == 4) {
573: ruleConditions.append(getPacRule(ruleValues[0],
574: ruleValues[1], ruleValues[2], ruleValues[3]));
575: } else if (ruleValues.length == 3) {
576: ruleConditions.append(getPacRule("*", ruleValues[0],
577: ruleValues[1], ruleValues[2]));
578:
579: }
580:
581: }
582: System.out
583: .println("rulecondition " + ruleConditions.toString());
584:
585: return ruleConditions.toString();
586:
587: }
588:
589: /**
590: * This function returns one conditional block for requested protocol:
591: * http/https/ftp/gopher to generate the pac file for manual settings
592: * @return string Returns conditional block
593: *
594: */
595: private static String getManualCondition(String protocol,
596: String host, int port) {
597: StringBuffer condition = new StringBuffer();
598: condition.append("if (url.substring(0,"
599: + (protocol.length() + 1) + ") == \"" + protocol
600: + ":\") {\n");
601: condition.append(" return \"PROXY " + host + ":" + port
602: + "\";\n");
603: condition.append(" } else ");
604: return condition.toString();
605: }
606:
607: /**
608: * This function replaces file:// with file:/// to allow URL connection
609: * @return string
610: *
611: */
612: private static String getFormatedAutoConfigURL(String autoConfigURL) {
613: if ((-1 == autoConfigURL.indexOf("file:///"))
614: && (-1 != autoConfigURL.indexOf("file://"))) {
615: return autoConfigURL.replaceFirst("file://", "file:///");
616: }
617: return autoConfigURL;
618: }
619:
620: /**
621: * manualConfigSetting
622: * This function is responsible for extracting the manual
623: * proxy host and port values.
624: * @return boolean Returns false is manual configuration is not set or
625: * if the configured proxy server information is incorrect.
626: *
627: */
628: public static boolean checkManualSetting(String configList) {
629: if (configList == null)
630: return false;
631:
632: configList = StringUtil.replaceAll(configList, "=", "://");
633: Param.setClientProxyInfo("MANUAL", configList);
634: Param.setProxyMethod("MANUAL");
635: return BrowserHelper.validateProxy();
636: }
637:
638: /**
639: * getNewfileLocation
640: * This function is responsible for popping up the file
641: * dialog to user and get the new location from the user
642: * @return String Returns the new config location
643: *
644: */
645: public static String getNewfileLocation(Component comp) {
646: String location = null;
647: JOptionPane.showMessageDialog(comp, Param.getString("pinfo.25",
648: "Please choose a directory"));
649: JFileChooser fc = new JFileChooser();
650: int returnVal = fc.showOpenDialog(comp);
651: if (returnVal == JFileChooser.APPROVE_OPTION) {
652: File file = fc.getSelectedFile();
653: location = file.getPath();
654: }
655: return location;
656: }
657:
658: /**
659: * checkLocation
660: * This function is responsible for checking the given
661: * pacfile location is writable or not
662: * @return String Returns the new config location
663: *
664: */
665: public static String checkLocation(String location, Component comp) {
666: System.out.println("check location " + location);
667: int index = location.lastIndexOf('/');
668: System.out.println("looking for a forward slah " + index);
669: if (-1 == index) {
670: System.out.println("looking for a backward double slash "
671: + index);
672: index = location.lastIndexOf('\\');
673: }
674: if (-1 == index) {
675: location = System.getProperty("user.dir") + File.separator
676: + location;
677: System.out.println("location " + location);
678: } else {
679: String tmpDir = Param.getTempDirectory();
680: if (!new File(tmpDir).isDirectory()) {
681: System.out.println("Not a valid directory");
682: location = getNewfileLocation(comp);
683: }
684:
685: }
686: return location;
687: }
688:
689: /**
690: * WritePacFile
691: * This function is responsible for writing the pacfile to
692: * local system.
693: *
694: *
695: */
696: public static String writePacFile(String pacfileLocation,
697: Component comp) {
698: System.out.println("writepacfile " + pacfileLocation);
699: // get a writable location for storing pac file
700: String location = checkLocation(pacfileLocation, comp);
701:
702: try {
703: FileOutputStream fout = new FileOutputStream(location);
704: fout.write(Param.getNewPACContent().getBytes());
705: fout.flush();
706: fout.close();
707:
708: } catch (Exception ex) {
709:
710: }
711:
712: return location;
713:
714: }
715:
716: /**
717: * Need to put all these parameters in to some proxyvalue object.. passing these as
718: * parameteres is not good...
719: * @param proxyTypeProxy
720: * @param proxyTypeAutoProxyUrl
721: * @param proxyTypeAutoDetect
722: * @param context
723: * @param mode
724: * @param autoconfigurl
725: * @param manaulinfo
726: * @return
727: */
728:
729: public static String processProxyInfo(long proxyTypeProxy,
730: long proxyTypeAutoProxyUrl, long proxyTypeAutoDetect,
731: Component context, String mode, String autoconfigurl,
732: String manaulinfo) {
733: boolean handled = false;
734: long lproxyMode = Long.valueOf(mode).longValue();
735:
736: System.out.println("proxy mode " + lproxyMode);
737:
738: // These variables holds the values for http or file protocol for autoconfig
739: String clientHost = "http://localhost:";
740: String fileProtocol = "file://";
741:
742: if ((lproxyMode & proxyTypeAutoDetect) == proxyTypeAutoDetect) {
743: System.out.println("Proxy Setting detected : AutoDetect");
744: ProxyletUI.setText(Param.getString("pinfo.16",
745: "Proxy Setting detected : AutoDetect"));
746: handled = BrowserHelper.checkAutoDetectSetting();
747: }
748:
749: if ((lproxyMode & proxyTypeAutoProxyUrl) == proxyTypeAutoProxyUrl) {
750: System.out.println("Autoconfig URL set");
751: handled = BrowserHelper.checkPACFileSetting(autoconfigurl);
752: }
753:
754: System.out.println("Autoconfig URL handled " + handled);
755: if (!handled && (lproxyMode & proxyTypeProxy) == proxyTypeProxy) {
756: handled = BrowserHelper.checkManualSetting(manaulinfo);
757: }
758: System.out.println("Manual URL handled " + handled);
759:
760: if (!handled) {
761: System.out.println("Direct " + handled);
762: Param.setClientProxyInfo("DIRECT", null);
763: }
764:
765: // Create the PAC file function
766: BrowserHelper.generatePacContent(Param.getBindPort());
767: String configLocation = null;
768: if (Param.isPacfileNeedToStore()) {
769: String pacfileLocation = BrowserHelper.writePacFile(Param
770: .getPacfileLocation(), context);
771:
772: Param.setPacfileLocation(pacfileLocation);
773: pacfileLocation = pacfileLocation.replace('\\', '/');
774: configLocation = fileProtocol + pacfileLocation;
775: } else {
776: configLocation = clientHost + Param.getBindPort()
777: + "/proxy.pac";
778: }
779:
780: return configLocation;
781: }
782:
783: /**
784: * Use the WPAD ( DNS ) protocol to retrive PAC file.
785: * @return
786: */
787: static boolean checkAutoDetectSetting() {
788:
789: try {
790: byte[] pacContent = WPAD.getPacContent();
791: String pacFileBody = new String(pacContent);
792: Param.setClientPACContent(pacFileBody);
793: extractProxyServerFromPAC(pacFileBody);
794: } catch (Exception e) {
795: ProxyletUI.setText(e.getMessage());
796: return false;
797: }
798:
799: return true;
800: }
801:
802: /**
803: * This class implements the WPAD protocol
804: * Ref: http://micro.uoregon.edu/net_access/wpad_rfc_1999.html
805: */
806: static class WPAD {
807:
808: /**
809: * The getPacContent gets the local domain, prefixes wpad to the domain
810: * and attempts to retrive pac content. It does this progressively to the
811: * subdomains till it gets the .pac or .dat file.
812: *
813: * @return Returns the pac content
814: */
815: static byte[] getPacContent() throws Exception {
816:
817: StringBuffer proxysettings = new StringBuffer();
818:
819: // findout the client IP and hostname
820: InetAddress ia = InetAddress.getLocalHost();
821: String hostName = ia.getHostName();
822: Log.debug("hostname = " + hostName);
823: String ipAddr = ia.getHostAddress();
824: Log.debug("ip = " + ipAddr);
825: // get the client's FQDN hostname (include dns domain)
826: hostName = InetAddress.getByName(ipAddr).getHostName();
827: Log.debug("FQDN hostname = " + hostName);
828:
829: // split the FQDN by hostname, subdomains and domains
830: String[] domainlist = hostName.split("\\.");
831:
832: // construction well known wpad dns name based client's dns domain
833:
834: int len = domainlist.length;
835: boolean found = false;
836: String wpadhost = "";
837:
838: for (int i = 1; i < len - 1; i++) {
839: wpadhost = "wpad";
840: for (int j = i; j < len; j++)
841: wpadhost += "." + domainlist[j];
842: Log.debug("WPAD - " + wpadhost);
843: ProxyletUI.setText(Param.getString("pinfo.17",
844: "WPAD: Trying host ")
845: + wpadhost);
846: try {
847: ia = InetAddress.getByName(wpadhost);
848: found = true;
849: break;
850: } catch (java.net.UnknownHostException uhe) {
851: }
852: }
853:
854: if (found) {
855:
856: ProxyletUI.setText(Param.getString("pinfo.13",
857: "Connecting to server ")
858: + " " + wpadhost);
859: Log.debug("Found WPAD dns name - " + wpadhost);
860: try {
861: // construct wpad URL
862: URL u = new URL("http://" + wpadhost + "/wpad.dat");
863: HttpURLConnection huc = (HttpURLConnection) u
864: .openConnection();
865: // set follow redirects. the default is set, just want to make sure
866: huc.setFollowRedirects(true);
867: huc.setRequestMethod("GET");
868: huc.connect();
869:
870: int code = huc.getResponseCode();
871: Log.debug("HTTP Return Code = " + code);
872:
873: if (code >= 200 && code < 300) {
874: // has the contents
875: //Get the input stream from the connection object
876: BufferedReader inStream = new BufferedReader(
877: new InputStreamReader(huc
878: .getInputStream()));
879:
880: String response = "";
881: // get the proxy pac file
882: while ((response = inStream.readLine()) != null) {
883: proxysettings.append(response + "\n");
884: }
885: // print the proxy pac file
886: Log
887: .debug("----------------------pac file begin---------------------");
888: Log.debug(proxysettings.toString());
889: Log
890: .debug("-----------------------pac file end----------------------");
891:
892: ProxyletUI
893: .setText(Param
894: .getString("pinfo.18",
895: "----------------------pac file begin---------------------"));
896: ProxyletUI.setText(proxysettings.toString());
897: ProxyletUI
898: .setText(Param
899: .getString("pinfo.19",
900: "----------------------pac file end---------------------"));
901:
902: } else {
903: Log
904: .debug("Error to retreive proxy pac file, http response code = "
905: + code);
906: }
907: huc.disconnect();
908: } catch (IOException e) {
909: Log.debug("Exception - " + e);
910: throw e;
911: }
912: } else {
913: Log.debug("could not find wpad host");
914: ProxyletUI.setText(Param.getString("pinfo.20",
915: "Cannot find WPAD host"));
916: }
917:
918: return (proxysettings != null) ? proxysettings.toString()
919: .getBytes() : null;
920: }
921: }
922: } // class BrowserHelper
|