package com.jgoetsch.eventtrader.source; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.ResponseHandler; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.LaxRedirectStrategy; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class JsChallengeRespondingHttpClient implements HttpClient { private Logger log = LoggerFactory.getLogger(JsChallengeRespondingHttpClient.class); private final HttpClient backend; public JsChallengeRespondingHttpClient() { this(null); } public JsChallengeRespondingHttpClient(HttpClient client) { super(); if (client == null) { this.backend = new DefaultHttpClient(); ((DefaultHttpClient)backend).setRedirectStrategy(new LaxRedirectStrategy()); } else this.backend = client; } public HttpResponse execute(HttpHost target, HttpRequest request) throws IOException { HttpContext defaultContext = null; return execute(target, request, defaultContext); } public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler) throws IOException { return execute(target, request, responseHandler, null); } public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException { HttpResponse resp = execute(target, request, context); return responseHandler.handleResponse(resp); } public HttpResponse execute(HttpUriRequest request) throws IOException { HttpContext context = null; return execute(request, context); } public HttpResponse execute(HttpUriRequest request, HttpContext context) throws IOException { URI uri = request.getURI(); HttpHost httpHost = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme()); return execute(httpHost, request, context); } public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler) throws IOException { return execute(request, responseHandler, null); } public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException { HttpResponse resp = execute(request, context); return responseHandler.handleResponse(resp); } public HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) throws IOException { HttpResponse response = backend.execute(target, request, context); if (response.getStatusLine().getStatusCode() == 503) { String content = EntityUtils.toString(response.getEntity()); Matcher tokenMatch = Pattern.compile("name=\"jschl_vc\" value=\"(\\w*)\"").matcher(content); if (tokenMatch.find()) { String jschl = tokenMatch.group(1); Matcher exprMatch = Pattern.compile("\\$\\('#jschl_answer'\\).val\\((\\d+)\\+(\\d+)\\*(\\d+)\\);").matcher(content); if (exprMatch.find()) { log.debug("Received challenge expression {}, jschl_vc={}", exprMatch.group(0), jschl); try { Thread.sleep(5850); } catch (InterruptedException e) {} long answer = Long.valueOf(exprMatch.group(1)) + Long.valueOf(exprMatch.group(2)) * Long.valueOf(exprMatch.group(3)); HttpPost chlResponseReq = new HttpPost(target.toURI()); try { List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("act", "jschl")); params.add(new BasicNameValuePair("jschl_vc", jschl)); params.add(new BasicNameValuePair("jschl_answer", String.valueOf(answer))); UrlEncodedFormEntity reqEntity = new UrlEncodedFormEntity(params, "UTF-8"); chlResponseReq.setEntity(reqEntity); } catch (UnsupportedEncodingException e) { log.error("Error encoding request entity", e); } response = backend.execute(target, chlResponseReq, context); } } } return response; } public ClientConnectionManager getConnectionManager() { return backend.getConnectionManager(); } public HttpParams getParams() { return backend.getParams(); } }