通过代理服务器连接到Azure存储帐户Microsoft Azure Storage SDK for Java

时间:2015-08-02 20:19:09

标签: java azure proxy azure-storage azure-storage-blobs

在我们的项目中,我们需要通过代理服务器(squid)访问Blob存储。

我们计划使用Microsoft Azure Storage SDK for Java version 2.2.0。 但看起来API并未提供设置代理。 我可以让它通过代理的唯一方法是设置系统属性

System.setProperty("http.proxyHost", "127.0.0.1");
System.setProperty("http.proxyPort", "3128");

但这会影响我的JVM上运行的所有服务,这会损害其他不应通过代理服务器的服务。

查看它看起来的java代码 com.microsoft.azure.storage.core.BaseRequest.createURLConnection(URI,RequestOptions,UriQueryBuilder,OperationContext)。在没有代理的情况下调用java.net.URL.openConnection()。 使用java.net.URL.openConnection(Proxy)可以提供所需的支持吗?

我觉得这不支持吗? 我在这里想念一下吗?

更新:我在azure-storage-java git中打开了issue,我很乐意得到您的输入,因为我想建议一个拉取请求。< / p>

3 个答案:

答案 0 :(得分:1)

到目前为止,还没有Java SDK API支持通过代理服务器直接访问Azure存储,因为BaseRequest类在函数“public static HttpConnection createURLConnection(...)”中错过了“url.openConnection(proxy)”。

根据我的经验,有两种方法可以帮助您实现访问功能。

一个是您可以通过java.net.Proxy类使用Azure存储REST API来访问存储服务。

Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(host, port));
URLConnection conn = url.openConnection(proxy);
And if you should be authorize proxy user & password, you can do it as the follows:
//Proxy-Authorization: Basic <Base64.encode(user:password)>
String headerKey = "Proxy-Authorization";
String headerValue = "Basic " + Base64.encode(user+":"+password);
conn.setRequestProperty(headerKey, headerValue);

最后一个是您可以修改Azure SDK API, 覆盖Class“BaseRequest” 中的方法“createURLConnection”以实现访问。 GitHub上的Azure Storage SDK v2.2.0项目为https://github.com/Azure/azure-storage-java/tree/v2.2.0/

注意:

public static HttpURLConnection createURLConnection(final URI uri,final RequestOptions options,UriQueryBuilder builder,final OperationContext opContext, java.net.Proxy proxy

final HttpURLConnection retConnection =(HttpURLConnection)resourceUrl.openConnection( proxy );

public static HttpURLConnection createURLConnection(final URI uri, final RequestOptions options, UriQueryBuilder builder, final OperationContext opContext, java.net.Proxy proxy) throws IOException, URISyntaxException, StorageException {
    if (builder == null) {
        builder = new UriQueryBuilder();
    }

    final URL resourceUrl = builder.addToURI(uri).toURL();

    final HttpURLConnection retConnection = (HttpURLConnection) resourceUrl.openConnection(proxy);

    if (options.getTimeoutIntervalInMs() != null && options.getTimeoutIntervalInMs() != 0) {
        builder.add(TIMEOUT, String.valueOf(options.getTimeoutIntervalInMs() / 1000));
    }

    // Note: ReadTimeout must be explicitly set to avoid a bug in JDK 6.
    // In certain cases, this bug causes an immediate read timeout exception to be thrown even if ReadTimeout is not set.
    retConnection.setReadTimeout(Utility.getRemainingTimeout(options.getOperationExpiryTimeInMs(), options.getTimeoutIntervalInMs()));

    // Note : accept behavior, java by default sends Accept behavior as text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
    retConnection.setRequestProperty(Constants.HeaderConstants.ACCEPT, Constants.HeaderConstants.XML_TYPE);
    retConnection.setRequestProperty(Constants.HeaderConstants.ACCEPT_CHARSET, Constants.UTF8_CHARSET);

    // Note : Content-Type behavior, java by default sends Content-type behavior as application/x-www-form-urlencoded for posts.
    retConnection.setRequestProperty(Constants.HeaderConstants.CONTENT_TYPE, Constants.EMPTY_STRING);

    retConnection.setRequestProperty(Constants.HeaderConstants.STORAGE_VERSION_HEADER,
        Constants.HeaderConstants.TARGET_STORAGE_VERSION);
    retConnection.setRequestProperty(Constants.HeaderConstants.USER_AGENT, getUserAgent());
    retConnection.setRequestProperty(Constants.HeaderConstants.CLIENT_REQUEST_ID_HEADER,
        opContext.getClientRequestID());

    return retConnection;
}

顺便说一下,你需要在每个CloudXXXClient(CloudBlobClient等)类中调用上面的方法。

答案 1 :(得分:1)

根据此问题以及由strazh issue-48打开的其他问题,由我打开issue-65后,代理支持在版本4.2.0中进行了改进,请参阅here

  

添加了对设置库范围代理的支持。默认代理可以   在OperationContext上设置。

有关完整示例,请参阅JUnits https://github.com/Azure/azure-storage-java/blob/master/microsoft-azure-storage-test/src/com/microsoft/azure/storage/GenericTests.java

查找testDefaultProxy和testProxy

答案 2 :(得分:1)

Azure存储团队已经发布了一个新的SDK(v10),现在通过HttpPipeline支持该代理。您可以通过将管道传递给StorageURL来在所有操作中共享管道,也可以通过将其传递给BlobURL对象在单个Blob中使用。

AnonymousCredentials creds = new AnonymousCredentials();

// Use PipelineOptions to define a retry strategy and a proxy - you can also pass your own HttpClient to this if you like
PipelineOptions po = new PipelineOptions();

// Proxy configuration shown here as a sample
HttpClientConfiguration configuration = new HttpClientConfiguration(
      new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 8888)), false); //pass true if the Proxy endpoint is HTTPS
po.client = HttpClient.createDefault(configuration);


// Create a URI with SAS token, and pass it to the PageBlobURL with an HttpPipeline created by createPipeline method
URL u = new URL("https://myaccount.blob.core.windows.net/mycontainer/myfile?sv=2017-04-17&sr=b&si=14169767-6354-41ed-a99b-c9db8dcc66bc&sig=8NUr%2BSpmRH%2BB2z%2FpQZDPDquTQ7rbgWfE9a6AePLlFT0%3D");
PageBlobURL blobURL = new PageBlobURL(u, PageBlobURL.createPipeline(creds, po));