Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sync origin #12

Merged
merged 20 commits into from
Feb 13, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
2c6f99d
GzipSource beginnings.
squarejesse Feb 3, 2014
1b25214
Merge pull request #510 from square/jwilson_0203_gzip_beginnings
swankjesse Feb 8, 2014
1f97e6b
Rename byteAt to getByte.
squarejesse Feb 8, 2014
cd16580
Fix some OkBuffer bugs.
squarejesse Feb 8, 2014
4c8ce7c
Merge pull request #516 from square/jwilson_0208_byte_at_to_get_byte
Feb 8, 2014
1151c98
Merge pull request #517 from square/jwilson_0208_buffer_fixes
Feb 8, 2014
acd45e1
Initial implementation of an OkHttp-backed curl clone.
JakeWharton Feb 6, 2014
de6d505
Merge pull request #514 from square/jw/okcurl
JakeWharton Feb 8, 2014
5d7fdba
fix #184: OkHttp no longer uses default ssl context.
Feb 9, 2014
f11832d
Merge pull request #518 from square/adrian.okclient-provided-sslcontext
swankjesse Feb 9, 2014
6587a86
Add -X to okcurl, permitting HEAD requests.
Feb 11, 2014
12f7e64
Merge pull request #522 from square/adrian.curl-X
JakeWharton Feb 11, 2014
d60d8e1
Use OkBuffer in spdy/3 source stream.
squarejesse Feb 9, 2014
a2cb34d
Merge pull request #519 from square/jwilson_0209_okbuffer_in_spdy3_so…
swankjesse Feb 11, 2014
72d5fae
Use OkBuffer in http/2 source stream
squarejesse Feb 11, 2014
545807e
Merge pull request #523 from square/jwilson_0211_okbuffer_in_http2_so…
swankjesse Feb 11, 2014
9c6a433
BufferedSource.
squarejesse Feb 12, 2014
c40cb63
Merge pull request #524 from square/jwilson_0211_buffered_source
Feb 12, 2014
c8507d0
Use OkBuffer in SpdyStream.
squarejesse Feb 12, 2014
8720ab4
Merge pull request #526 from square/jwilson_0212_okbuffer_in_spdystream
swankjesse Feb 12, 2014
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,6 @@ public void processConnection() throws Exception {
.handler(spdySocketHandler).build();
openSpdyConnections.put(spdyConnection, Boolean.TRUE);
openClientSockets.remove(socket);
spdyConnection.readConnectionHeader();
return;
}

Expand Down
94 changes: 94 additions & 0 deletions okcurl/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.squareup.okhttp</groupId>
<artifactId>parent</artifactId>
<version>2.0.0-SNAPSHOT</version>
</parent>

<artifactId>okcurl</artifactId>
<name>OkCurl</name>

<dependencies>
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>okhttp</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.mortbay.jetty.npn</groupId>
<artifactId>npn-boot</artifactId>
</dependency>
<dependency>
<groupId>io.airlift</groupId>
<artifactId>airline</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.squareup.okhttp.curl.Main</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.skife.maven</groupId>
<artifactId>really-executable-jar-maven-plugin</artifactId>
<version>1.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>really-executable-jar</goal>
</goals>
</execution>
</executions>
<configuration>
<flags>-Xbootclasspath/p:$0</flags>
</configuration>
</plugin>
</plugins>
</build>
</project>
208 changes: 208 additions & 0 deletions okcurl/src/main/java/com/squareup/okhttp/curl/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
package com.squareup.okhttp.curl;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.squareup.okhttp.ConnectionPool;
import com.squareup.okhttp.Failure;
import com.squareup.okhttp.Headers;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import io.airlift.command.Arguments;
import io.airlift.command.Command;
import io.airlift.command.HelpOption;
import io.airlift.command.Option;
import io.airlift.command.SingleCommand;
import java.io.IOException;
import java.io.InputStream;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import static java.util.concurrent.TimeUnit.SECONDS;

@Command(name = Main.NAME, description = "A curl for the next-generation web.")
public class Main extends HelpOption implements Runnable, Response.Receiver {
static final String NAME = "okcurl";
static final int DEFAULT_TIMEOUT = -1;

public static void main(String... args) {
SingleCommand.singleCommand(Main.class).parse(args).run();
}

private static String versionString() {
try {
Properties prop = new Properties();
InputStream in = Main.class.getResourceAsStream("/okcurl-version.properties");
prop.load(in);
in.close();
return prop.getProperty("version");
} catch (IOException e) {
throw new AssertionError("Could not load okcurl-version.properties.");
}
}

private static String protocols() {
return Joiner.on(", ").join(Lists.transform(Arrays.asList(Protocol.values()),
new Function<Protocol, String>() {
@Override public String apply(Protocol protocol) {
return protocol.name.utf8();
}
}));
}

@Option(name = { "-X", "--request" }, description = "Specify request command to use",
allowedValues = { "GET", "HEAD" })
public String method = "GET";

@Option(name = { "-H", "--header" }, description = "Custom header to pass to server")
public List<String> headers;

@Option(name = { "-A", "--user-agent" }, description = "User-Agent to send to server")
public String userAgent = NAME + "/" + versionString();

@Option(name = "--connect-timeout", description = "Maximum time allowed for connection (seconds)")
public int connectTimeout = DEFAULT_TIMEOUT;

@Option(name = "--read-timeout", description = "Maximum time allowed for reading data (seconds)")
public int readTimeout = DEFAULT_TIMEOUT;

@Option(name = { "-L", "--location" }, description = "Follow redirects")
public boolean followRedirects;

@Option(name = { "-k", "--insecure" },
description = "Allow connections to SSL sites without certs")
public boolean allowInsecure;

@Option(name = { "-i", "--include" }, description = "Include protocol headers in the output")
public boolean showHeaders;

@Option(name = { "-e", "--referer" }, description = "Referer URL")
public String referer;

@Option(name = { "-V", "--version" }, description = "Show version number and quit")
public boolean version;

@Arguments(title = "url", description = "Remote resource URL")
public String url;

private OkHttpClient client;

@Override public void run() {
if (showHelpIfRequested()) {
return;
}
if (version) {
System.out.println(NAME + " " + versionString());
System.out.println("Protocols: " + protocols());
return;
}

client = getConfiguredClient();
Request request = getConfiguredRequest();
client.enqueue(request, this);

// Immediately begin triggering an executor shutdown so that after execution of the above
// request the threads do not stick around until timeout.
client.getDispatcher().getExecutorService().shutdown();
}

private OkHttpClient getConfiguredClient() {
OkHttpClient client = new OkHttpClient();
client.setFollowProtocolRedirects(followRedirects);
if (connectTimeout != DEFAULT_TIMEOUT) {
client.setConnectTimeout(connectTimeout, SECONDS);
}
if (readTimeout != DEFAULT_TIMEOUT) {
client.setReadTimeout(readTimeout, SECONDS);
}
if (allowInsecure) {
client.setSslSocketFactory(createInsecureSslSocketFactory());
}
// If we don't set this reference, there's no way to clean shutdown persistent connections.
client.setConnectionPool(ConnectionPool.getDefault());
return client;
}

private Request getConfiguredRequest() {
Request.Builder request = new Request.Builder();
request.method(method, null);
request.url(url);
if (headers != null) {
for (String header : headers) {
String[] parts = header.split(":", -1);
request.header(parts[0], parts[1]);
}
}
if (referer != null) {
request.header("Referer", referer);
}
request.header("User-Agent", userAgent);
return request.build();
}

@Override public void onFailure(Failure failure) {
failure.exception().printStackTrace();
close();
}

@Override public boolean onResponse(Response response) throws IOException {
if (showHeaders) {
System.out.println(response.statusLine());
Headers headers = response.headers();
for (int i = 0, count = headers.size(); i < count; i++) {
System.out.println(headers.name(i) + ": " + headers.value(i));
}
System.out.println();
}

Response.Body body = response.body();
byte[] buffer = new byte[1024];
while (body.ready()) {
int c = body.byteStream().read(buffer);
if (c == -1) {
close();
return true;
}

System.out.write(buffer, 0, c);
}
close();
return false;
}

private void close() {
client.getConnectionPool().evictAll(); // Close any persistent connections.
}

private static SSLSocketFactory createInsecureSslSocketFactory() {
try {
SSLContext context = SSLContext.getInstance("TLS");
TrustManager permissive = new X509TrustManager() {
@Override public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}

@Override public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}

@Override public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
context.init(null, new TrustManager[] { permissive }, null);
return context.getSocketFactory();
} catch (Exception e) {
throw new AssertionError(e);
}
}
}
1 change: 1 addition & 0 deletions okcurl/src/main/resources/okcurl-version.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
version=${project.version}
Original file line number Diff line number Diff line change
Expand Up @@ -404,4 +404,17 @@ public static void asciiLowerCase(byte[] bytes) {
public static byte asciiLowerCase(byte c) {
return 'A' <= c && c <= 'Z' ? (byte) (c + 'a' - 'A') : c;
}

public static int reverseBytesShort(short s) {
int i = s & 0xffff;
return (i & 0xff00) >>> 8
| (i & 0x00ff) << 8;
}

public static int reverseBytesInt(int i) {
return (i & 0xff000000) >>> 24
| (i & 0x00ff0000) >>> 8
| (i & 0x0000ff00) << 8
| (i & 0x000000ff) << 24;
}
}
Loading