Java tutorial
/******************************************************************************* * Copyright (c) 2014,2015 Hideki Yatomi * All rights reserved. This program and the accompanying materials are made * available under the terms of the Eclipse Public License v1.0 which * accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html ******************************************************************************/ package net.yatomiya.nicherry.services.bbs; import java.io.*; import java.net.*; import java.util.*; import org.eclipse.e4.core.contexts.*; import com.squareup.okhttp.*; import com.squareup.okhttp.Authenticator; import net.yatomiya.e4.services.*; import net.yatomiya.e4.util.*; import net.yatomiya.nicherry.*; import net.yatomiya.nicherry.model.bbs.*; public class BBSHttpClient extends StandardHttpClient { private IEclipseContext context; private CookieManager cookieManager; private String proxyCredentials; private AccessIntervalInterceptor intervalInterceptor; BBSHttpClient(IEclipseContext context) { super(); this.context = context; // setRetryOnConnectionFailure(false); // setFollowRedirects(false); // setFollowSslRedirects(false); getDispatcher().setMaxRequestsPerHost(1); cookieManager = context.get(PersistenceService.class).get( BBSHttpClient.class.getName() + "." + CookieManager.class.getName(), () -> new CookieManager()); setCookieHandler(cookieManager); setAuthenticator(new Authenticator() { @Override public Request authenticate(Proxy proxy, Response response) throws IOException { return null; } @Override public Request authenticateProxy(Proxy proxy, Response response) throws IOException { if (getProxy() != null && proxyCredentials != null) { if (!proxyCredentials.equals(response.request().header("Proxy-Authorization"))) { return response.request().newBuilder().header("Proxy-Authorization", proxyCredentials) .build(); } } return null; } }); intervalInterceptor = new AccessIntervalInterceptor(); interceptors().add((chain) -> interceptRequest(chain)); interceptors().add((chain) -> interceptGetDat(chain)); { PreferenceService prefs = context.get(PreferenceService.class); prefs.subscribe(this, NPreferences.NODE, NPreferences.NETWORK_PROXY_ENABLE, event -> applyProxyPreference()); prefs.subscribe(this, NPreferences.NODE, NPreferences.NETWORK_PROXY_HOST, event -> applyProxyPreference()); prefs.subscribe(this, NPreferences.NODE, NPreferences.NETWORK_PROXY_PORT, event -> applyProxyPreference()); prefs.subscribe(this, NPreferences.NODE, NPreferences.NETWORK_PROXY_BASIC_USERNAME, event -> applyProxyPreference()); prefs.subscribe(this, NPreferences.NODE, NPreferences.NETWORK_PROXY_BASIC_PASSWORD, event -> applyProxyPreference()); prefs.subscribe(this, NPreferences.NODE, NPreferences.BBS_NETWORK_CONNECT_INTERVAL_PER_HOST, event -> intervalInterceptor.interval = Integer.valueOf(event.getValue())); } } void shutdown() { cancelAll(); context.get(PreferenceService.class).unsubscribe(this); } @Override public Call execute(Request request, Callback callback, boolean isSynchronous) { Call call = newCall(request); if (isSynchronous) { try { Response response = call.execute(); callback.onResponse(response); } catch (IOException e) { callback.onFailure(request, e); } } else { call.enqueue(callback); } return call; } public void clearCookies() { cookieManager.getCookieStore().removeAll(); } @Override public OkHttpClient clone() { throw new UnsupportedOperationException(); } void applyProxyPreference() { PreferenceService prefs = context.get(PreferenceService.class); boolean enable = Boolean.valueOf(prefs.getString(NPreferences.NODE, NPreferences.NETWORK_PROXY_ENABLE)); String host = prefs.getString(NPreferences.NODE, NPreferences.NETWORK_PROXY_HOST); int port = Integer.valueOf(prefs.getString(NPreferences.NODE, NPreferences.NETWORK_PROXY_PORT)); String username = prefs.getString(NPreferences.NODE, NPreferences.NETWORK_PROXY_BASIC_USERNAME); String password = prefs.getString(NPreferences.NODE, NPreferences.NETWORK_PROXY_BASIC_PASSWORD); if (enable && !JUtils.isEmpty(host)) { setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(host, port))); } else { setProxy(Proxy.NO_PROXY); } if (enable && !JUtils.isEmpty(username) && !JUtils.isEmpty(password)) { proxyCredentials = Credentials.basic(username, password); } else { proxyCredentials = null; } } Response interceptRequest(Interceptor.Chain chain) throws IOException { Request.Builder builder = chain.request().newBuilder(); builder.header("User-Agent", NUtils.getPreference(NPreferences.NETWORK_HTTP_USER_AGENT)); intervalInterceptor.waitInterval(chain.request()); return chain.proceed(builder.build()); } Response interceptGetDat(Interceptor.Chain chain) throws IOException { Object tag = chain.request().tag(); ThreadUpdateHandler handler = null; if ((tag != null) && (tag instanceof ThreadUpdateHandler)) handler = (ThreadUpdateHandler) tag; if (handler == null) { return chain.proceed(chain.request()); } else { MThread thread = handler.getModel(); return ((ThreadUpdateHandler) thread.getProcessor().getUpdateHandler()).processIntercept(chain); } } class AccessIntervalInterceptor { int interval = 0; class HostData { String host; long lastAccessTime = -1; } Map<String, HostData> dataMap = new HashMap<>(); public void waitInterval(Request request) { String host = request.url().getHost(); HostData data; synchronized (this) { data = dataMap.get(host); if (data == null) { data = new HostData(); data.host = host; dataMap.put(host, data); } } synchronized (data) { long current = System.currentTimeMillis(); if (data.lastAccessTime >= 0) { long elapsed = current - data.lastAccessTime; long remain = interval - elapsed; if (remain > 0) { try { Thread.sleep(remain); } catch (InterruptedException e) { } } data.lastAccessTime = current; } } } } }