mirror of
https://github.com/Rogiel/httpchannel
synced 2025-12-05 23:22:51 +00:00
Adds -SNAPSHOT to Maven version parameter and few modifications to API
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>httpchannel</artifactId>
|
||||
<groupId>com.rogiel.httpchannel</groupId>
|
||||
<version>1.0.0</version>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
<artifactId>httpchannel-util</artifactId>
|
||||
@@ -12,7 +12,7 @@
|
||||
<dependency>
|
||||
<groupId>com.rogiel.httpchannel</groupId>
|
||||
<artifactId>httpchannel-api</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
package com.rogiel.httpchannel.captcha;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URI;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.rogiel.httpchannel.http.HttpContext;
|
||||
@@ -13,46 +12,73 @@ import com.rogiel.httpchannel.util.PatternUtils;
|
||||
import com.rogiel.httpchannel.util.htmlparser.HTMLPage;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
* This class provides utility methods to extract an {@link ImageCaptcha} from
|
||||
* an page containing an Google ReCaptcha CAPTCHA embedded into it.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class ReCaptchaExtractor {
|
||||
/**
|
||||
* This pattern extracts the SITE-ID from the Ajax ReCaptcha API
|
||||
*/
|
||||
private static final Pattern CAPTCHA_ID_PATTERN = Pattern
|
||||
.compile("Recaptcha\\.create\\(\"([0-9A-z|_|\\-]*)\", ");
|
||||
private static final Pattern CAPTCHA_URL_PATTERN = Pattern
|
||||
private static final Pattern CAPTCHA_URI_PATTERN = Pattern
|
||||
.compile("http://www\\.google\\.com/recaptcha/api/challenge\\?k=([0-9A-z|\\-]*)(&(.*))?");
|
||||
private static final Pattern CAPTCHA_IMAGE_PATTERN = Pattern
|
||||
.compile("challenge : '(.*)'");
|
||||
|
||||
private static final String CHALLENGE_BASE_URL = "http://www.google.com/recaptcha/api/challenge?ajax=1&k=";
|
||||
private static final String IMAGE_BASE_URL = "http://www.google.com/recaptcha/api/image?c=";
|
||||
private static final String CHALLENGE_BASE_URI = "http://www.google.com/recaptcha/api/challenge?ajax=1&k=";
|
||||
private static final String IMAGE_BASE_URI = "http://www.google.com/recaptcha/api/image?c=";
|
||||
|
||||
/**
|
||||
* Extracts the {@link ImageCaptcha} for an ReCAPTCHA using the standard JS
|
||||
* include method
|
||||
*
|
||||
* @param page
|
||||
* the page
|
||||
* @param ctx
|
||||
* the {@link HttpContext}
|
||||
* @return the {@link ImageCaptcha} embedded at the given <code>page</code>
|
||||
*/
|
||||
public static ImageCaptcha extractCaptcha(HTMLPage page, HttpContext ctx) {
|
||||
final String url = page.findScriptSrc(CAPTCHA_URL_PATTERN);
|
||||
if (url == null)
|
||||
final String uri = page.findScriptSrc(CAPTCHA_URI_PATTERN);
|
||||
if (uri == null)
|
||||
return null;
|
||||
try {
|
||||
return doExtract(ctx.get(url).asString());
|
||||
return doExtract(ctx.get(uri).asString());
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the {@link ImageCaptcha} for an ReCAPTCHA using the Ajax API
|
||||
*
|
||||
* @param page
|
||||
* the page
|
||||
* @param ctx
|
||||
* the {@link HttpContext}
|
||||
* @return the {@link ImageCaptcha} contained at the given <code>page</code>
|
||||
*/
|
||||
public static ImageCaptcha extractAjaxCaptcha(HTMLPage page, HttpContext ctx) {
|
||||
final String siteID = page.findScript(CAPTCHA_ID_PATTERN, 1);
|
||||
try {
|
||||
return doExtract(ctx.get(CHALLENGE_BASE_URL + siteID).asString());
|
||||
return doExtract(ctx.get(CHALLENGE_BASE_URI + siteID).asString());
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually performs the extracting job.
|
||||
*
|
||||
* @param content
|
||||
* the page content
|
||||
* @return the {@link ImageCaptcha}
|
||||
*/
|
||||
private static ImageCaptcha doExtract(String content) {
|
||||
final String id = PatternUtils.find(CAPTCHA_IMAGE_PATTERN, content, 1);
|
||||
try {
|
||||
return new ImageCaptcha(id, new URL(IMAGE_BASE_URL + id));
|
||||
} catch (MalformedURLException e) {
|
||||
return null;
|
||||
}
|
||||
return new ImageCaptcha(id, URI.create(IMAGE_BASE_URI + id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,13 +11,13 @@ import org.apache.http.client.methods.HttpGet;
|
||||
public class GetRequest extends Request {
|
||||
private long position = 0;
|
||||
|
||||
public GetRequest(HttpContext ctx, String url) {
|
||||
super(ctx, url);
|
||||
public GetRequest(HttpContext ctx, String uri) {
|
||||
super(ctx, uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpResponse request() throws IOException {
|
||||
final HttpGet get = new HttpGet(url);
|
||||
final HttpGet get = new HttpGet(uri);
|
||||
if (position > 0)
|
||||
get.addHeader("Range", "bytes=" + position + "-");
|
||||
return ctx.client.execute(get);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
package com.rogiel.httpchannel.http;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
@@ -22,19 +22,19 @@ public class HttpContext {
|
||||
*/
|
||||
protected DefaultHttpClient client = new DefaultHttpClient();
|
||||
|
||||
public GetRequest get(String url) {
|
||||
return new GetRequest(this, url);
|
||||
public GetRequest get(String uri) {
|
||||
return new GetRequest(this, uri);
|
||||
}
|
||||
|
||||
public GetRequest get(URL url) {
|
||||
return get(url.toString());
|
||||
public GetRequest get(URI uri) {
|
||||
return get(uri.toString());
|
||||
}
|
||||
|
||||
public PostRequest post(String url) {
|
||||
return new PostRequest(this, url);
|
||||
public PostRequest post(String uri) {
|
||||
return new PostRequest(this, uri);
|
||||
}
|
||||
|
||||
public PostMultipartRequest multipartPost(String url) {
|
||||
return new PostMultipartRequest(this, url);
|
||||
public PostMultipartRequest multipartPost(String uri) {
|
||||
return new PostMultipartRequest(this, uri);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,14 +18,14 @@ import com.rogiel.httpchannel.service.channel.LinkedUploadChannelContentBody;
|
||||
public class PostMultipartRequest extends PostRequest {
|
||||
private final MultipartEntity entity;
|
||||
|
||||
public PostMultipartRequest(HttpContext ctx, String url) {
|
||||
super(ctx, url);
|
||||
public PostMultipartRequest(HttpContext ctx, String uri) {
|
||||
super(ctx, uri);
|
||||
this.entity = new MultipartEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpResponse request() throws IOException {
|
||||
final HttpPost post = new HttpPost(url);
|
||||
final HttpPost post = new HttpPost(uri);
|
||||
post.setEntity(entity);
|
||||
return ctx.client.execute(post);
|
||||
}
|
||||
|
||||
@@ -17,13 +17,13 @@ import org.apache.http.message.BasicNameValuePair;
|
||||
public class PostRequest extends Request {
|
||||
protected final List<NameValuePair> params = new ArrayList<NameValuePair>();
|
||||
|
||||
public PostRequest(HttpContext ctx, String url) {
|
||||
super(ctx, url);
|
||||
public PostRequest(HttpContext ctx, String uri) {
|
||||
super(ctx, uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpResponse request() throws IOException {
|
||||
final HttpPost post = new HttpPost(url);
|
||||
final HttpPost post = new HttpPost(uri);
|
||||
post.setEntity(new UrlEncodedFormEntity(params));
|
||||
return ctx.client.execute(post);
|
||||
}
|
||||
|
||||
@@ -15,11 +15,11 @@ import com.rogiel.httpchannel.util.htmlparser.HTMLPage;
|
||||
|
||||
public abstract class Request {
|
||||
protected final HttpContext ctx;
|
||||
protected final String url;
|
||||
protected final String uri;
|
||||
|
||||
public Request(HttpContext ctx, String url) {
|
||||
public Request(HttpContext ctx, String uri) {
|
||||
this.ctx = ctx;
|
||||
this.url = url;
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public abstract HttpResponse request() throws IOException;
|
||||
@@ -59,7 +59,7 @@ public abstract class Request {
|
||||
});
|
||||
}
|
||||
|
||||
public String getURL() {
|
||||
return url;
|
||||
public String getURI() {
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package com.rogiel.httpchannel.service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URI;
|
||||
|
||||
import com.rogiel.httpchannel.service.Downloader.DownloaderConfiguration;
|
||||
import com.rogiel.httpchannel.service.channel.InputStreamDownloadChannel;
|
||||
@@ -23,9 +23,9 @@ import com.rogiel.httpchannel.service.exception.DownloadNotResumableException;
|
||||
public abstract class AbstractDownloader<C extends DownloaderConfiguration>
|
||||
implements Downloader<C> {
|
||||
/**
|
||||
* The download URL
|
||||
* The download URI
|
||||
*/
|
||||
protected final URL url;
|
||||
protected final URI uri;
|
||||
|
||||
/**
|
||||
* The {@link Downloader} configuration
|
||||
@@ -35,13 +35,13 @@ public abstract class AbstractDownloader<C extends DownloaderConfiguration>
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param url
|
||||
* the download url
|
||||
* @param uri
|
||||
* the download uri
|
||||
* @param configuration
|
||||
* the configuration object
|
||||
*/
|
||||
protected AbstractDownloader(URL url, C configuration) {
|
||||
this.url = url;
|
||||
protected AbstractDownloader(URI uri, C configuration) {
|
||||
this.uri = uri;
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
package com.rogiel.httpchannel.service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URI;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.http.Header;
|
||||
@@ -39,8 +39,8 @@ public abstract class AbstractHttpDownloader<C extends DownloaderConfiguration>
|
||||
extends AbstractDownloader<C> implements Downloader<C> {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
protected AbstractHttpDownloader(URL url, C configuration) {
|
||||
super(url, configuration);
|
||||
protected AbstractHttpDownloader(URI uri, C configuration) {
|
||||
super(uri, configuration);
|
||||
}
|
||||
|
||||
protected long getContentLength(HttpResponse response) {
|
||||
@@ -70,7 +70,7 @@ public abstract class AbstractHttpDownloader<C extends DownloaderConfiguration>
|
||||
.getStatusLine().getStatusCode() == HttpStatus.SC_PARTIAL_CONTENT))
|
||||
throw new DownloadLinkNotFoundException();
|
||||
|
||||
final String filename = FilenameUtils.getName(request.getURL());
|
||||
final String filename = FilenameUtils.getName(request.getURI());
|
||||
final long contentLength = getContentLength(response);
|
||||
return createInputStreamChannel(response.getEntity().getContent(),
|
||||
contentLength, filename);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
package com.rogiel.httpchannel.service;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import com.rogiel.httpchannel.http.GetRequest;
|
||||
@@ -45,23 +45,23 @@ public abstract class AbstractHttpService extends AbstractService implements
|
||||
return channel;
|
||||
}
|
||||
|
||||
public GetRequest get(String url) {
|
||||
return http.get(url);
|
||||
public GetRequest get(String uri) {
|
||||
return http.get(uri);
|
||||
}
|
||||
|
||||
public GetRequest get(URL url) {
|
||||
return http.get(url);
|
||||
public GetRequest get(URI uri) {
|
||||
return http.get(uri);
|
||||
}
|
||||
|
||||
public PostRequest post(String url) {
|
||||
return http.post(url);
|
||||
public PostRequest post(String uri) {
|
||||
return http.post(uri);
|
||||
}
|
||||
|
||||
public PostRequest post(URL url) {
|
||||
return post(url.toString());
|
||||
public PostRequest post(URI uri) {
|
||||
return post(uri.toString());
|
||||
}
|
||||
|
||||
public PostMultipartRequest multipartPost(String url) {
|
||||
return http.multipartPost(url);
|
||||
public PostMultipartRequest multipartPost(String uri) {
|
||||
return http.multipartPost(uri);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
package com.rogiel.httpchannel.service.channel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URI;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channel;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
@@ -29,19 +30,43 @@ import com.rogiel.httpchannel.service.UploadChannel;
|
||||
import com.rogiel.httpchannel.service.exception.UploadLinkNotFoundException;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
* This channel is linked onto another {@link Channel} that actually writes data
|
||||
* into the network stream.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class LinkedUploadChannel implements UploadChannel {
|
||||
/**
|
||||
* The logger instance
|
||||
*/
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
|
||||
/**
|
||||
* The destionation {@link Channel}. Data writted is forwarded to this
|
||||
* channel.
|
||||
*/
|
||||
private WritableByteChannel channel;
|
||||
/**
|
||||
* The close callback, that notifies once the channel has been closed
|
||||
*/
|
||||
private final LinkedUploadChannelCloseCallback closeCallback;
|
||||
|
||||
/**
|
||||
* The length of the data being uploaded
|
||||
*/
|
||||
private final long length;
|
||||
/**
|
||||
* The file name
|
||||
*/
|
||||
private final String filename;
|
||||
private URL downloadLink;
|
||||
/**
|
||||
* Only set when {@link #close()} is called and the download has finished.
|
||||
*/
|
||||
private URI downloadLink;
|
||||
|
||||
/**
|
||||
* Whether the channel is still open or not
|
||||
*/
|
||||
private boolean open = true;
|
||||
|
||||
public LinkedUploadChannel(LinkedUploadChannelCloseCallback closeCallback,
|
||||
@@ -55,11 +80,11 @@ public class LinkedUploadChannel implements UploadChannel {
|
||||
public int write(ByteBuffer src) throws IOException {
|
||||
if (channel == null)
|
||||
throw new IOException("Channel is not linked yet");
|
||||
if(!open)
|
||||
if (!open)
|
||||
throw new ClosedChannelException();
|
||||
try {
|
||||
return channel.write(src);
|
||||
} catch(IOException e) {
|
||||
} catch (IOException e) {
|
||||
close();
|
||||
throw e;
|
||||
}
|
||||
@@ -77,7 +102,7 @@ public class LinkedUploadChannel implements UploadChannel {
|
||||
logger.debug("Download link returned by service is {}", downloadLink);
|
||||
if (downloadLink == null)
|
||||
throw new UploadLinkNotFoundException();
|
||||
this.downloadLink = new URL(downloadLink);
|
||||
this.downloadLink = URI.create(downloadLink);
|
||||
}
|
||||
|
||||
public interface LinkedUploadChannelCloseCallback {
|
||||
@@ -95,16 +120,33 @@ public class LinkedUploadChannel implements UploadChannel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getDownloadLink() {
|
||||
public URI getDownloadLink() {
|
||||
return downloadLink;
|
||||
}
|
||||
|
||||
/**
|
||||
* Links this {@link Channel} to the destionation {@link Channel}. All data
|
||||
* written in this channel will be redirected to the destination
|
||||
* {@link Channel}.
|
||||
*
|
||||
* @param channel
|
||||
* the target channel
|
||||
* @throws IOException
|
||||
* if the channel is already linked or the destination channel
|
||||
* is closed
|
||||
*/
|
||||
protected void linkChannel(WritableByteChannel channel) throws IOException {
|
||||
if (this.channel != null)
|
||||
throw new IOException("This channel is already linked.");
|
||||
throw new IOException("This channel is already linked");
|
||||
if (!channel.isOpen())
|
||||
throw new IOException("The destination channel is closed");
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if the channel is linked with the destination
|
||||
* {@link Channel}
|
||||
*/
|
||||
public boolean isLinked() {
|
||||
return channel != null;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.rogiel.httpchannel.util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URI;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
@@ -65,7 +65,7 @@ public class ChannelUtils {
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
public static URL upload(UploadService<?> service, Path path)
|
||||
public static URI upload(UploadService<?> service, Path path)
|
||||
throws IOException {
|
||||
final UploadChannel uploadChannel = UploadServices
|
||||
.upload(service, path).openChannel();
|
||||
|
||||
@@ -35,14 +35,14 @@ public class HttpClientUtils {
|
||||
private static final ExecutorService threadPool = Executors
|
||||
.newCachedThreadPool();
|
||||
|
||||
public static HttpResponse get(HttpClient client, String url)
|
||||
public static HttpResponse get(HttpClient client, String uri)
|
||||
throws IOException {
|
||||
return client.execute(new HttpGet(url));
|
||||
return client.execute(new HttpGet(uri));
|
||||
}
|
||||
|
||||
public static String getString(HttpClient client, String url)
|
||||
public static String getString(HttpClient client, String uri)
|
||||
throws IOException {
|
||||
return toString(get(client, url));
|
||||
return toString(get(client, uri));
|
||||
}
|
||||
|
||||
public static String execute(HttpClient client, HttpUriRequest request)
|
||||
|
||||
@@ -104,7 +104,7 @@ public class HTMLPage {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to find a link that has an URL following the given pattern
|
||||
* Tries to find a link that has an URI following the given pattern
|
||||
*
|
||||
* @param pattern
|
||||
* the pattern
|
||||
@@ -119,11 +119,11 @@ public class HTMLPage {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to find a frame that has an URL following the given pattern
|
||||
* Tries to find a frame that has an URI following the given pattern
|
||||
*
|
||||
* @param pattern
|
||||
* the pattern
|
||||
* @return the iframe url, if found. <code>null</code> otherwise
|
||||
* @return the iframe uri, if found. <code>null</code> otherwise
|
||||
*/
|
||||
public String findFrame(final Pattern pattern) {
|
||||
for (final TagNode tag : filter(TagNode.class, new FramePatternFilter(
|
||||
@@ -134,11 +134,11 @@ public class HTMLPage {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to find a image that has an URL following the given pattern
|
||||
* Tries to find a image that has an URI following the given pattern
|
||||
*
|
||||
* @param pattern
|
||||
* the pattern
|
||||
* @return the iframe url, if found. <code>null</code> otherwise
|
||||
* @return the iframe uri, if found. <code>null</code> otherwise
|
||||
*/
|
||||
public String findImage(final Pattern pattern) {
|
||||
for (final ImageTag tag : filter(ImageTag.class,
|
||||
@@ -154,7 +154,7 @@ public class HTMLPage {
|
||||
*
|
||||
* @param pattern
|
||||
* the pattern
|
||||
* @return the URL found, if any. <code>null</code> otherwise
|
||||
* @return the URI found, if any. <code>null</code> otherwise
|
||||
*/
|
||||
public String findFormAction(final Pattern pattern) {
|
||||
for (final FormTag tag : filter(FormTag.class,
|
||||
|
||||
Reference in New Issue
Block a user