http.proxyPort: the port number, the default value being 80.
http.nonProxyHosts:a list of hosts that should be reached directly, bypassing the proxy. This is a list of patterns separated by ‘|’. The patterns may start or end with a ‘*’ for wildcards. Any host matching one of these patterns will be reached through a direct connection instead of through a proxy.
As you can see, with Java SE 5.0, the developer gains quite a bit of control and flexibility when it comes to proxies. Still, there are situations where one would like to decide which proxy to use dynamically, for instance to do some load balancing between proxies, or depending on the destination, in which case the API described so far would be quite cumbersome. That’s where the ProxySelector comes into play.
The best thing about the ProxySelector is that it is plugable! Which means that if you have needs that are not covered by the default one, you can write a replacement for it and plug it in!
public static void main(String[] args) {
MyProxySelector ps = new MyProxySelector(ProxySelector.getDefault());
ProxySelector.setDefault(ps);
// rest of the application
}
public class MyProxySelector extends ProxySelector {
// Keep a reference on the previous default
ProxySelector defsel = null;
/*
* Inner class representing a Proxy and a few extra data
*/
class InnerProxy {
Proxy proxy;
SocketAddress addr;
// How many times did we fail to reach this proxy?
int failedCount = 0;
InnerProxy(InetSocketAddress a) {
this(a, Proxy.Type.HTTP);
}
InnerProxy(InetSocketAddress a, Proxy.Type type) {
addr = a;
proxy = new Proxy(type, a);
}
SocketAddress address() {
return addr;
}
Proxy toProxy() {
return proxy;
}
int failed() {
return ++failedCount;
}
}
/*
* A list of proxies, indexed by their address.
*/
HashMap<SocketAddress, InnerProxy> proxies = new HashMap<SocketAddress, InnerProxy>();
MyProxySelector(ProxySelector def) {
// Save the previous default
defsel = def;
// Populate the HashMap (List of proxies)
InnerProxy i = new InnerProxy(new InetSocketAddress("webcache1.example.com", 8080));
proxies.put(i.address(), i);
i = new InnerProxy(new InetSocketAddress("webcache2.example.com", 8080));
proxies.put(i.address(), i);
i = new InnerProxy(new InetSocketAddress("webcache3.example.com", 8080));
proxies.put(i.address(), i);
}
/*
* This is the method that the handlers will call.
* Returns a List of proxy.
*/
public java.util.List<Proxy> select(URI uri) {
// Let's stick to the specs.
if (uri == null) {
throw new IllegalArgumentException("URI can't be null.");
}
/* 这里可以指定你自己的规则/配置
* If it's a http (or https) URL, then we use our own list.
*/
String protocol = uri.getScheme();
if ("http".equalsIgnoreCase(protocol) ||
"https".equalsIgnoreCase(protocol)) {
ArrayList<Proxy> l = new ArrayList<Proxy>();
for (InnerProxy p : proxies.values()) {
l.add(p.toProxy());
}
return l;
}
/*
* Not HTTP or HTTPS (could be SOCKS or FTP)
* defer to the default selector.
*/
if (defsel != null) {
return defsel.select(uri);
} else {
ArrayList<Proxy> l = new ArrayList<Proxy>();
l.add(Proxy.NO_PROXY);
return l;
}
}
/*
* Method called by the handlers when it failed to connect
* to one of the proxies returned by select().
*/
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
// Let's stick to the specs again.
if (uri == null || sa == null || ioe == null) {
throw new IllegalArgumentException("Arguments can't be null.");
}
/*
* Let's lookup for the proxy
*/
InnerProxy p = proxies.get(sa);
if (p != null) {
/*
* It's one of ours, if it failed more than 3 times
* let's remove it from the list.
*/
if (p.failed() >= 3)
proxies.remove(sa);
} else {
/*
* Not one of ours, let's delegate to the default.
*/
if (defsel != null)
defsel.connectFailed(uri, sa, ioe);
}
}
}
可以看到 PATT 模式空间把前面两行连到一起了,匹配到 5 的时刻其实模式空间的内容为 3\n4\n5,然后执行 d 这就相当于删除前两行了。
该命令会多输出最后一行:由于到最后一行,N 又读取了一次下一行(读到结束符),直接就返回没有执行 D 了。sed 文档中的描述如下:
12345678910
`D'
If pattern space contains no newline, start a normal new cycle as
if the `d' command was issued. Otherwise, delete text in the
pattern space up to the first newline, and restart cycle with the
resultant pattern space, without reading a new line of input.
`N'
Add a newline to the pattern space, then append the next line of
input to the pattern space. If there is no more input then `sed'
exits without processing any more commands.
修复就是:读到最后一行的时刻就不读下一行了:
1
[root@ansible sedsed]# echo -e "1\n2\n3\n4\n5\n6\n7\n8\n9\n10" | sed '/5/,+3d;:go;1,2!{P;$!N;D};N;bgo'