Java tutorial
/* * Overchan Android (Meta Imageboard Client) * Copyright (C) 2014-2015 miku-nyan <https://github.com/miku-nyan> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package nya.miku.wishmaster.http.recaptcha; import java.io.InputStream; import java.util.regex.Matcher; import java.util.regex.Pattern; import nya.miku.wishmaster.api.interfaces.CancellableTask; import nya.miku.wishmaster.http.ExtendedMultipartBuilder; import nya.miku.wishmaster.http.streamer.HttpRequestModel; import nya.miku.wishmaster.http.streamer.HttpResponseModel; import nya.miku.wishmaster.http.streamer.HttpStreamer; import org.apache.http.HttpEntity; import org.apache.http.client.HttpClient; import android.graphics.Bitmap; import android.graphics.BitmapFactory; /** * 2.0, fallback (noscript).<br> * , ? {@link #obtain(String, CancellableTask, HttpClient, String)}.<br> * , ? {@link #checkCaptcha(String, CancellableTask)}. * @author miku-nyan * */ /* Google ? ?? ? org.apache.http "deprecated" API 22 (Android 5.1) * ? ? ??? ? ?? apache-hc httpclient 4.3.5.1-android * ?: https://issues.apache.org/jira/browse/HTTPCLIENT-1632 */ @SuppressWarnings("deprecation") public class Recaptcha2 { // ? private static final String RECAPTCHA_FALLBACK_URL = "://www.google.com/recaptcha/api/fallback?k="; // ? Challenge private static final String RECAPTCHA_IMAGE_URL = "://www.google.com/recaptcha/api2/payload?c="; /** ? */ public Bitmap bitmap; /** challenge */ public String challenge; private HttpClient httpClient; private String scheme; private String publicKey; /** * * @param publicKey * @param task , * @param httpClient , ? ? ? ? * @param scheme (http https), ? null, "http" * @return */ public static Recaptcha2 obtain(String publicKey, CancellableTask task, HttpClient httpClient, String scheme) throws RecaptchaException { try { if (scheme == null) scheme = "http"; Recaptcha2 recaptcha = new Recaptcha2(); recaptcha.httpClient = httpClient; recaptcha.scheme = scheme; recaptcha.publicKey = publicKey; String response = HttpStreamer.getInstance().getStringFromUrl( scheme + RECAPTCHA_FALLBACK_URL + publicKey, HttpRequestModel.builder().setGET().build(), httpClient, null, task, false); Matcher matcher = Pattern.compile("name=\"c\" value=\"([\\w-]+)").matcher(response); if (matcher.find()) { recaptcha.challenge = matcher.group(1); HttpResponseModel responseModel = HttpStreamer.getInstance().getFromUrl( scheme + RECAPTCHA_IMAGE_URL + recaptcha.challenge + "&k=" + publicKey, HttpRequestModel.builder().setGET().build(), httpClient, null, task); try { InputStream imageStream = responseModel.stream; recaptcha.bitmap = BitmapFactory.decodeStream(imageStream); } finally { responseModel.release(); } return recaptcha; } else throw new RecaptchaException("can't parse recaptcha challenge answer"); } catch (Exception e) { if (e instanceof RecaptchaException) { throw (RecaptchaException) e; } else { throw new RecaptchaException(e); } } } /** * * @param answer * @param task ?? * @return ? ? - ?, "g-recaptcha-response" * @throws RecaptchaException ? ? */ public String checkCaptcha(String answer, CancellableTask task) throws RecaptchaException { try { HttpEntity postEntity = ExtendedMultipartBuilder.create().addString("c", this.challenge) .addString("response", answer).build(); String response = HttpStreamer.getInstance().getStringFromUrl( scheme + RECAPTCHA_FALLBACK_URL + publicKey, HttpRequestModel.builder().setPOST(postEntity).build(), httpClient, null, task, false); String hash = ""; Matcher matcher = Pattern .compile("fbc-verification-token(?:.*?)<textarea[^>]*>([^<]*)<", Pattern.DOTALL) .matcher(response); if (matcher.find()) hash = matcher.group(1); if (hash.length() > 0) { return hash; } else { throw new RecaptchaException("RECAPTCHA: probably the incorrect answer (hash is empty)"); } } catch (Exception e) { if (e instanceof RecaptchaException) { throw (RecaptchaException) e; } else { throw new RecaptchaException(e); } } } private Recaptcha2() { } }