Giter Site home page Giter Site logo

azure-storage-android's Introduction

Microsoft Azure Storage SDK for Android

This project provides a client library for Android that makes it easy to consume Microsoft Azure Storage services. For documentation please see the AndroidDocs.

If you are looking for the Azure Storage Java SDK, please visit https://github.com/Azure/azure-storage-java.

Features

  • Blob
    • Create/Read/Update/Delete containers
    • Create/Read/Update/Delete blobs
    • Advanced Blob Operations
  • Queue
    • Create/Delete Queues
    • Insert/Peek Queue Messages
    • Advanced Queue Operations
  • Table
    • Create/Read/Update/Delete tables
    • Create/Read/Update/Delete entities
    • Batch operations
    • Advanced Table Operations

Getting Started

Download

Option 1: Source Zip

To download a copy of the source code, click "Download ZIP" on the right side of the page or click here. Unzip and navigate to the microsoft-azure-storage folder.

Option 2: Source Via Git

To get the source code of the SDK via git just type:

git clone git://github.com/Azure/azure-storage-android.git
cd ./azure-storage-android/microsoft-azure-storage

Option 3: aar via Gradle

To get the binaries of this library as distributed by Microsoft, ready for use within your project, you can use Gradle.

First, add mavenCentral to your repositories by adding the following to your gradle build file:

repositories {
    mavenCentral()
}

Then, add a dependency by adding the following to your gradle build file:

dependencies {
    compile 'com.microsoft.azure.android:azure-storage-android:2.0.0@aar'
}

Option 4: aar via Maven

To get the binaries of this library as distributed by Microsoft, ready for use within your project, you can use Maven.

<dependency>
	<groupId>com.microsoft.azure.android</groupId>
	<artifactId>azure-storage-android</artifactId>
	<version>2.0.0</version>
	<type>aar</type>
</dependency>

Minimum Requirements and Setup

  • Jackson-Core is used for JSON parsing.
  • Android 4.0/15+
  • (Optional) Gradle or Maven

This library is currently tested to work on Android versions 4.0+. Compatibility with older versions is not guaranteed.

Usage

To use this SDK to call Microsoft Azure storage services, you need to first create an account.

Samples are provided in the microsoft-azure-storage-samples folder. The unit tests in microsoft-azure-storage-test can also be helpful.

Make sure the storage client library is added as a project dependency. From Android Studio, go to File -> Project Structure. Click on the module (either sample or test). If 'microsoft-azure-storage' is not listed as a dependy, click the '+' sign. Then click module dependency and select 'microsoft-azure-storage'.

If using Maven or Gradle, Jackson-Core should be automatically added to the build path. Otherwise, please download the jar and add it to your build path. Also, please make sure that the jar will be added to your project's apk. To do this in Android Studio, go to File -> Project Structure -> Modules. Click the Dependencies tab. Click the '+' sign and click 'File Dependency'. Navigate the .jar.

Code Samples

Runnable samples for blob, queue, and table may be found in the microsoft-azure-storage-samples directory. To run these samples, specify a connection string in the MainActivity class and add a dependency on the Android client library. For additional information on using the Android client library, the Java general documentation and Java How To guides for blobs, queues, tables may be helpful.

Need Help?

Be sure to check out the Azure Developer Forums on MSDN or the Developer Forums on Stack Overflow if you have trouble with the provided code.

Contribute Code or Provide Feedback

If you would like to become an active contributor to this project please follow the instructions provided in Azure Projects Contribution Guidelines.

If you encounter any bugs with the library please file an issue in the Issues section of the project.

Learn More

azure-storage-android's People

Contributors

asorrin-msft avatar bryant1410 avatar dadoonet avatar emgerner-msft avatar erezvani1529 avatar esummers-msft avatar m-moris avatar microsoft-github-policy-service[bot] avatar mirobers avatar pemari-msft avatar zezha-msft avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

azure-storage-android's Issues

container.CreateIfNotExists() throws NullReferenceException

Hi,

Downloaded latest code. Trying to run sample with my Azure account and getting following error.

Caused by: java.lang.NullPointerException
at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:632)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:347)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:503)
at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:136)
at com.microsoft.azure.storage.StorageException.translateException(StorageException.java:76)
at com.microsoft.azure.storage.core.ExecutionEngine.executeWithRetry(ExecutionEngine.java:267)
at com.microsoft.azure.storage.blob.CloudBlobContainer.exists(CloudBlobContainer.java:747)
at com.microsoft.azure.storage.blob.CloudBlobContainer.createIfNotExists(CloudBlobContainer.java:358)
at com.microsoft.azure.storage.blob.CloudBlobContainer.createIfNotExists(CloudBlobContainer.java:334)
at com.azures.AzureActivity$AzureCreateTask.doInBackground(AzureActivity.java:41)
at com.azures.AzureActivity$AzureCreateTask.doInBackground(AzureActivity.java:33)

After uploading Image to blogstorage I am getting sas URL appended to image url

Hello, I am using android azure storage to upload images. It was working fine with library version:

compile 'com.microsoft.azure.android:azure-storage-android:0.5.1@aar'

But, Now I have updated library to latest one that is as below:

compile 'com.microsoft.azure.android:azure-storage-android:0.7.0'

So, Now I got Image URL after uploading Image. That Image URL contain URL+SAS string with that.
e.g:
https://MYDOMAIN.blob.core.windows.net/images/5/cover/image_f279e54467224e1997788fda8e178c09.jpg?sv=2015-04-05&sr=c&sig=/gpTWMi9HZIP6xyw0no0d5sjAfo6Tx3rHRSOpjoB42w=&st=2015-12-21T07:37:41Z&se=2015-12-21T08:07:41Z&sp=w

So, I guess there is issue with the library that It gives SAS url along with Image URL.

Do I need to update the code which is working fine with the above library version or there is bug available in new storage library?

Please reply to me issue related to this.
Thanks.

Sincerely,
Shreyash

Unexpected attempt to get register for a value without a register

Trying to generate a signed apk for release publish in Store. And this error pops-up while building. I have used the implementation dependency method and also with git clone.

Unexpected attempt to get register for a value without a register in method void com.microsoft.azure.storage.CloudStorageAccount.<clinit>().``

This issue is related with minifyEnabled true , and proguard.

upload file OutOfMemoryError

FATAL EXCEPTION: pool-3-thread-1
Process: com.superdata.cxim, PID: 17973
java.lang.OutOfMemoryError
at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:156)
at java.io.BufferedInputStream.read(BufferedInputStream.java:288)
at com.microsoft.azure.storage.core.Utility.writeToOutputStream(Utility.java:1177)
at com.microsoft.azure.storage.core.Utility.writeToOutputStream(Utility.java:1089)
at com.microsoft.azure.storage.blob.BlobOutputStream.write(BlobOutputStream.java:645)
at com.microsoft.azure.storage.blob.CloudBlockBlob.upload(CloudBlockBlob.java:676)
at com.microsoft.azure.storage.blob.CloudBlob.uploadFromFile(CloudBlob.java:1672)
at com.microsoft.azure.storage.blob.CloudBlob.uploadFromFile(CloudBlob.java:1644)
at com.chaoxiang.imrestful.OkHttpUtils$AzureClient$1.run(OkHttpUtils.java:120)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)

Test equipment is ximi4.
My simple code(phonegap.rar file size is 3GB):

      try {
        CloudStorageAccount account = CloudStorageAccount.parse(storageConnectionString);
        CloudBlobClient blobClient = account.createCloudBlobClient();
        CloudBlobContainer container = blobClient.getContainerReference("cxim");
        container.createIfNotExists();

        BlobContainerPermissions containerPermissions = new BlobContainerPermissions();
        containerPermissions.setPublicAccess(BlobContainerPublicAccessType.CONTAINER);
        container.uploadPermissions(containerPermissions);
        CloudBlockBlob blob1 = container.getBlockBlobReference("phonegap.rar");
        String path = "/storage/emulated/0/BaiduNetdisk/0/Phonegap/phonegap.rar";
        blob1.uploadFromFile(path);

      } catch (Exception e) {
         e.printStackTrace();
      }

Threads Locked in Socket IO Library Version 0.5.1

I've noticed an issue in shutting down my app where threads running various queries through this library get stuck for upwards of 10 minutes. This appears consistent with some path through the library in which socket timeouts are not properly set.

The issue can be duplicated by running a query on a phone with no SIM card, with very poor, but still connected, WiFi. My test involves achieving this poor connectivity by either walking to the end of the hallway, or hanging out in the elevator 10 floors above my office, starting a ton of queries, then shutting down my application. This behavior cannot be duplicated by either disabling WiFi on the device or completely walking out of WiFi range.

The threads in question will not exit until
A: user toggles WiFi on the device,
B: user walks back into WiFi range, or
C: some extremely long default timeout triggers (>10 minutes)

The locked up query threads in question are running CloudTable.execute on various simple queries against my table storage account. TableRequestOptions are all default, except for setting a maximum execution time in milliseconds of 10000. On all CloudTable instances, I have run cloudTable.getServiceClient().getDefaultRequestOptions().setRetryPolicyFactory(new RetryNoRetry()).

It is rather difficult to pull full stack traces, as the bug has generally resolved itself by the time I can return to my desk, as I am thus back within WiFi range. I have managed to pull one such stack trace however:

at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method) at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:320) at com.android.okhttp.Connection.upgradeToTls(Connection.java:1285) at com.android.okhttp.Connection.connect(Connection.java:1197) at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:392) at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:295) at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:373) at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:323) at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:491) at com.android.okhttp.internal.http.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105) at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:25) at com.microsoft.azure.storage.core.ExecutionEngine.executeWithRetry(ExecutionEngine.java:123) at com.microsoft.azure.storage.core.LazySegmentedIterator.hasNext(LazySegmentedIterator.java:109) The above stack trace may not be exactly with the 0.5.1 release, however I can state that the issue in my app remains. I have built some tools to show the states of each thread in this frozen state. Locked up threads are generally in one of:

A. libcore.io.Posix.connect(Native Method),
B. com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method), or
C. com.android.org.conscrypt.NativeCrypto.SSL_read(Native Method)

All threads in question have been interrupted, and their interrupted flag is set at the time of determining their stack traces.

I am currently hoping that I have missed some simple setting in the client application, (There's no handy dandy kill all open connections method is there?) or that the library has missed some socket timeout, as I truly do not want to track this to issues in Posix or NativeCrypto.

Please let me know if there is any more information you would need to track this down, and thank you for providing the library that makes my application possible,

-Dan

container.CreateIfNotExists() throws NullReferenceException

I tried to use the code snippet on your documentation.

        CloudStorageAccount account = CloudStorageAccount.parse(storageConnectionString);
        CloudBlobClient serviceClient = account.createCloudBlobClient();

        // Container name must be lower case.
        CloudBlobContainer container = serviceClient.getContainerReference("myimages");
        container.createIfNotExists();

It threw NullReferenceException while calling container.createIfNotExists(). I'm quite sure I have a valid storage account.

Thanks for looking,
Peter

Unavailable ".withClientClaims()" method.

I just cloned the repository and when I try to run testapps.testapp it I get the following error:
error: cannot find symbol .withClientClaims(requestOptions.getPoPClientClaims())

Deleting a directory is not working

I'm trying to delete a previously created directory. I've made sure that it's empty and that it exists, but everytime I use the delete function, I'm rejected with a 404 and a Error Message = 'The specified resource does not exist.' which triggers a StorageException. It is weird in many ways because I can create directories, create files, even delete files but I can't delete directories.

I have a valid SasToken, with rcwdl privileges.

My connection string is as follows:

FileEndpoint=https://kasne.file.core.windows.net;SharedAccessSignature=sv=2015-12-11&sr=s&sig=xxx&st=2017-08-08T15%3A10%3A20Z&se=2017-08-09T15%3A25%3A20Z&sp=rcwdl
and my shareName is also valid (1d707d905f6b4ccaa27bd665fd528f9c).

Here is the code I use:

CloudStorageAccount storageAccount = CloudStorageAccount.parse(getConnectionString());
// Create the file storage client.
CloudFileClient fileClient = storageAccount.createCloudFileClient();
CloudFileShare share = fileClient.getShareReference(getShareName());
CloudFileDirectory rootDirectory = share.getRootDirectoryReference();
CloudFileDirectory folderToDelete= rootDirectory.getDirectoryReference("folderToDelete");
//I broke down the deleteIfExists() function in two to make sure the folder exists
//as I'll have other things to do if the folder exists, but using directly deleteIfExists() give the same
//result as delete()
if(folderToDelete.exists()) { //returns true
    folderToDelete.delete(); //returns a storage exception
}

This is the response I get when executing the exists() function:

{09eea61a-b69a-429b-a6a0-8b0ffff51bcd}: {Starting operation.}
{09eea61a-b69a-429b-a6a0-8b0ffff51bcd}: {Starting operation with location 'PRIMARY' per location mode 'PRIMARY_ONLY'.}
{09eea61a-b69a-429b-a6a0-8b0ffff51bcd}: {Starting request to 'https://kasne.file.core.windows.net/1d707d905f6b4ccaa27bd665fd528f9c/folderToDelete?sr=s&st=2017-08-08T15%3A10%3A20Z&api-version=2017-04-17&sp=rcwdl&restype=directory&se=2017-08-09T15%3A25%3A20Z&sv=2015-12-11&sig=xxx' at 'null'.}
{09eea61a-b69a-429b-a6a0-8b0ffff51bcd}: {Waiting for response.}
{09eea61a-b69a-429b-a6a0-8b0ffff51bcd}: {Response received. Status code = '200', Request ID = '88b3f82f-001a-0049-3bf3-104952000000', Content-MD5 = 'null', ETag = '"0x8D4D8ACF2D46C17"', Date = 'Wed, 09 Aug 2017 09:39:31 GMT'.}
{09eea61a-b69a-429b-a6a0-8b0ffff51bcd}: {A network error occurred before the HTTP response status and headers were received.}
{09eea61a-b69a-429b-a6a0-8b0ffff51bcd}: {Processing response headers.}
{09eea61a-b69a-429b-a6a0-8b0ffff51bcd}: {Response headers were processed successfully.}
{09eea61a-b69a-429b-a6a0-8b0ffff51bcd}: {Processing response body.}
{09eea61a-b69a-429b-a6a0-8b0ffff51bcd}: {Response body was parsed successfully.}
{09eea61a-b69a-429b-a6a0-8b0ffff51bcd}: {Operation completed.}

And this is the response for my actual delete request:

{4ec40b80-76b4-4fbe-8d33-5282b9e3e03c}: {Starting operation.}
{4ec40b80-76b4-4fbe-8d33-5282b9e3e03c}: {Starting operation with location 'PRIMARY' per location mode 'PRIMARY_ONLY'.}
{4ec40b80-76b4-4fbe-8d33-5282b9e3e03c}: {Starting request to 'https://kasne.file.core.windows.net/1d707d905f6b4ccaa27bd665fd528f9c/folderToDelete?restype=directory' at 'null'.}
{4ec40b80-76b4-4fbe-8d33-5282b9e3e03c}: {Waiting for response.}
{4ec40b80-76b4-4fbe-8d33-5282b9e3e03c}: {Response received. Status code = '404', Request ID = '88b3f830-001a-0049-3cf3-104952000000', Content-MD5 = 'null', ETag = 'null', Date = 'Wed, 09 Aug 2017 09:39:31 GMT'.}
{4ec40b80-76b4-4fbe-8d33-5282b9e3e03c}: {A network error occurred before the HTTP response status and headers were received.}
{4ec40b80-76b4-4fbe-8d33-5282b9e3e03c}: {Processing response headers.}
{4ec40b80-76b4-4fbe-8d33-5282b9e3e03c}: {Response headers were processed successfully.}
{4ec40b80-76b4-4fbe-8d33-5282b9e3e03c}: {Operation did not return the expected result or returned an exception.}
{4ec40b80-76b4-4fbe-8d33-5282b9e3e03c}: {Checking if the operation should be retried. Retry count = '0', HTTP status code = '404', Error Message = 'The specified resource does not exist.'.}
{4ec40b80-76b4-4fbe-8d33-5282b9e3e03c}: {The next location has been set to 'PRIMARY', per location mode 'PRIMARY_ONLY'.}
{4ec40b80-76b4-4fbe-8d33-5282b9e3e03c}: {Retry policy did not allow for a retry. Failing. Error Message = 'The specified resource does not exist.'.}

I noticed that my SasToken is attached as a query parameter when doing the exists() request and not when doing my delete(), is this normal ? I looked at the Rest api documentation and it seems that the delete call needs a authorization header and I don't know if it's present in the call from the library.

Is there support to get progress during a large file upload?

I'm using this method to upload some files on Blob (some files are large and take several minutes to upload).

    private void updateFilesOnBlob(){
        try {
            String timestamp = Tools.generateTimeStamp();

            // Retrieve storage account from connection-string.
            CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString);

            // Create the blob client.
            CloudBlobClient blobClient = storageAccount.createCloudBlobClient();

            // Retrieve reference to a previously created container.
            CloudBlobContainer container = blobClient.getContainerReference(CONTAINER_NAME);

            // Upload each file on Blob
            for (int i = 0; i< pathsArrayList.size(); i++) {
                // Define the path to a local file.
                final String filePath = pathsArrayList.get(i);
                CloudBlockBlob blob = container.getBlockBlobReference(timestamp + "/" + filenameFromPath(pathsArrayList.get(i)));
                File source = new File(filePath);
                blob.upload(new FileInputStream(source), source.length());
            }
        }
        catch (Exception e)
        {
            // Output the stack trace.
            e.printStackTrace();
        }
    }

As you can see, I use blob.upload() to start uploading the file. Is there any way to get the progress percentage and update the UI during the upload?

CloudBlockBlob generated a wrong SAS token

first of all, I can upload files to Azure Blob Storage Service.
I'm try to generate SAS URL but failed.

static String generateBlobUrl( CloudBlockBlob blob ){

    Log.v("Test",generateBlobUrl--begin--");
    try {
        SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy();

        EnumSet aSet = EnumSet.noneOf( SharedAccessAccountPermissions.class );
        aSet.add( SharedAccessAccountPermissions.READ );
        aSet.add( SharedAccessAccountPermissions.WRITE );
        aSet.add( SharedAccessAccountPermissions.LIST );
        policy.setPermissions( aSet );

        GregorianCalendar calendar = new GregorianCalendar( TimeZone.getTimeZone("UTC"));
        calendar.setTime(new Date());
        policy.setSharedAccessStartTime(calendar.getTime());
        calendar.add( Calendar.HOUR, 24);
        policy.setSharedAccessExpiryTime(calendar.getTime());


        String sasToken = blob.generateSharedAccessSignature(policy, null );
        String host = "https://mystorage.blob.core.windows.net/"+ blob.getContainer().getName() +"/"+ blob.getName();
        String url = host +"?"+ sasToken;
        Log.v("Test",generateBlobUrl========sasToken="+ sasToken );
        Log.v("Test",generateBlobUrl========host="+ host );
        Log.v("Test",generateBlobUrl========url="+ url );
        return url;
    }
    catch ( Exception e){
        e.printStackTrace();
        Log.v("Test",generateBlobUrl--error=" + e.getLocalizedMessage() );
    }

    return null;
}

1, sasToken is wrong.
log: sasToken=sig=GMqjezkLl1MSAqTyybfweB0hKvD3B5qhK9Q2ihhJefA%3D&st=2018-11-08T09%3A10%3A14Z&se=2018-11-09T09%3A10%3A14Z&sv=2017-04-17&sr=b

  1. datetime format is wrong.
  2. there is no "spr=https" in this sasToken

2, url is wrong too.
log: url=https://mystorage.blob.core.windows.net/d89ad74fbfd74ea5969da0f5588e387b/AIRecord/20181108170953_audio.wav?sig=GMqjezkLl1MSAqTyybfweB0hKvD3B5qhK9Q2ihhJefA%3D&st=2018-11-08T09%3A10%3A14Z&se=2018-11-09T09%3A10%3A14Z&sv=2017-04-17&sr=b

when i try download from this url, i see this error:

AuthenticationFailed Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:d60e6e38-801e-00d3-3047-778133000000 Time:2018-11-08T09:45:58.9178592Z sp is mandatory. Cannot be empty

Runtime Exception: Failed resolution of: Ljavax/xml/stream/XMLOutputFactory

Really surprised on how tricky this problem is. Unable to proceed further. I really don't know how to fix this. Tried all combinations. So basically com.microsoft.azure.storage seems like pure Java library. javax.xml.stream is missing.

Please help me here.

I'm building everything in Android Studio. So basically my Andorid App has to work. It is struggling to find the javax.xml.stream.* packages.

Resource leaking when create table

I've got the following strict mode warning when I call myTable.createIfNotExists()

E/StrictMode: A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
                                                                          java.lang.Throwable: Explicit termination method 'close' not called
                                                                              at dalvik.system.CloseGuard.open(CloseGuard.java:180)
                                                                              at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:288)
                                                                              at com.android.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:103)
                                                                              at com.android.okhttp.Connection.connect(Connection.java:143)
                                                                              at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:185)
                                                                              at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128)
                                                                              at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341)
                                                                              at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
                                                                              at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
                                                                              at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:453)
                                                                              at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:404)
                                                                              at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:536)
                                                                              at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105)
                                                                              at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:25)
                                                                              at com.microsoft.azure.storage.core.ExecutionEngine.executeWithRetry(ExecutionEngine.java:119)
                                                                              at com.microsoft.azure.storage.table.QueryTableOperation.performRetrieve(QueryTableOperation.java:176)
                                                                              at com.microsoft.azure.storage.table.TableOperation.execute(TableOperation.java:696)
                                                                              at com.microsoft.azure.storage.table.CloudTable.exists(CloudTable.java:882)
                                                                              at com.microsoft.azure.storage.table.CloudTable.createIfNotExists(CloudTable.java:287)
                                                                              at com.microsoft.azure.storage.table.CloudTable.createIfNotExists(CloudTable.java:262)
                                                                             

Slow speed download

Noticed very slow download speed via downloadToFile.

I have test file on 50 megs. Powershell or Storage explorer downloads it via seconds but android takes fair minutes to download it.

Even if I use downloadRange with chunks of 1Mb it is slow.

example needed to use sas for uploading image file

Hello, I have check your repo. That is more about to upload blob and text file to azure storage server.
I have seen your one of the document here that says that you can also use sas to upload the file.

https://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-shared-access-signature-part-2/#part-2-create-a-console-application-to-test-the-shared-access-signatures

Here in one of my client has created method from which i got sas. Now i have to use that sas to upload the file. But i am not getting proper step or way ti use it.

I need some more information on this, If possible i also want to have your repo to be updated with the example of uploading file using sas.

Thanks.

Sincerely,
Shreyash

Unable to resolve hos

Found it generate exception then there is no internet. Exception fired then accessing CloudBlobContainer like

container.exists()

or

CloudBlockBlob blob1 = container
.getBlockBlobReference("Name.ext");

Exception is -
Unable to resolve host "SOMENAME.blob.core.windows.net": No address associated with hostname

Do I need to check internet connection my self (in this case I am afraid I still cannot do it in most proper way) or this library has build in mechanism to check this?

Not able to upload image to blob storage - exception com.microsoft.azure.storage.StorageException: The specified resource does not exist. in line -> blobFromSASCredential.uploadFromFile(mPhotoFileUri.getPath());

Here's my code in onCreate method :

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_to_do);
    btnPreview = (Button) findViewById(R.id.buttonPreview);
    btnUpload = (Button) findViewById(R.id.buttonUpload);

    btnPreview.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            takePicture(v);
        }
    });

    btnUpload.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            uploadPhoto(v);

        }
    });

}

Other methods called from onCreate(directly or indirectly) -

// Create a File object for storing the photo
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix /
".jpg", /
suffix /
storageDir /
directory */
);
return image;
}

public void takePicture(View view) {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        // Create the File where the photo should go
        try {
            mPhotoFile = createImageFile();
        } catch (IOException ex) {
            // Error occurred while creating the File
            //
        }
        // Continue only if the File was successfully created
        if (mPhotoFile != null) {
            mPhotoFileUri = Uri.fromFile(mPhotoFile);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mPhotoFileUri);
            startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
        }
    }
}

public void uploadPhoto(View view) {
    MobileServiceClient mClient = null;
    try {
        mClient = new MobileServiceClient(
                "https://twokilo.azure-mobile.net/", // Replace with the above Site URL
                "bprbEdBfMdPozKNKnLcUQKPEgUKgof22",           // replace with the Application Key
                this);
    } catch (Exception e) {
    }
    if (mClient == null) {
        return;
    }
    final MobileServiceTable<Prescription> prescriptionTable = mClient.getTable("medic_orders_prescriptions", Prescription.class);
    // Create a new item
    final Prescription prescription = new Prescription();

    prescription.setUser("test");
    prescription.setMedic_order("test");
    prescription.setFull_flag(true);
    prescription.setNote("Test Note");
    prescription.setContainerName("prescriptions");

    // Use a unigue GUID to avoid collisions.
    UUID uuid = UUID.randomUUID();
    String uuidInString = uuid.toString();
    prescription.setResourceName(uuidInString);

    // Send the item to be inserted. When blob properties are set this
    // generates an SAS in the response.
    AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            try {
                android.os.Debug.waitForDebugger();
                final Prescription entity = prescriptionTable.insert(prescription).get();
                ;

                // If we have a returned SAS, then upload the blob.
                if (entity.getSasQueryString() != null) {

                    // Get the URI generated that contains the SAS
                    // and extract the storage credentials.
                    StorageCredentials cred =
                            new StorageCredentialsSharedAccessSignature(entity.getSasQueryString());
                    URI imageUri = new URI(entity.getPrescription());

                    // Upload the new image as a BLOB from a stream.
                    CloudBlockBlob blobFromSASCredential =
                            new CloudBlockBlob(imageUri, cred);
                    String fileName = mPhotoFileUri.toString();
                    blobFromSASCredential.uploadFromFile(mPhotoFileUri.getPath());
                }
            } catch (final Exception e) {
                Log.i("exception", "fat gyi");
            }
            return null;
        }
    };

    task.execute();

}

}

Problem uploading a file

I have simple code to upload a file to file storage. The file actually uploads fine although the log spits out this error continually.

`52373 [pool-1-thread-1] INFO root - {ab818704-fa6b-45c5-89a3-a335b6292ea0}: {Starting request to 'https://xxxxx.file.core.windows.net/xxxxx-container/TestFile6?comp=range' at 'Thu, 16 Aug 2018 10:50:20 GMT'.}

52375 [pool-1-thread-1] INFO root - {ab818704-fa6b-45c5-89a3-a335b6292ea0}: {Writing request data.}

55547 [pool-1-thread-1] INFO root - {ab818704-fa6b-45c5-89a3-a335b6292ea0}: {Request data was written successfully.}

55547 [pool-1-thread-1] INFO root - {ab818704-fa6b-45c5-89a3-a335b6292ea0}: {Waiting for response.}

56021 [pool-1-thread-1] INFO root - {ab818704-fa6b-45c5-89a3-a335b6292ea0}: {Response received. Status code = '201', Request ID = '368ec890-101a-003c-1f4e-359c26000000', Content-MD5 = 'ONflMbmKJ1gJjlP1NVcwIw==', ETag = '"0x8D6036611C8A382"', Date = 'Thu, 16 Aug 2018 10:50:23 GMT'.}

56022 [pool-1-thread-1] INFO root - {ab818704-fa6b-45c5-89a3-a335b6292ea0}: {A network error occurred before the HTTP response status and headers were received.}
56024 [pool-1-thread-1] INFO root - {ab818704-fa6b-45c5-89a3-a335b6292ea0}: {Processing response headers.}

56026 [pool-1-thread-1] INFO root - {ab818704-fa6b-45c5-89a3-a335b6292ea0}: {Response headers were processed successfully.}
56026 [pool-1-thread-1] INFO root - {ab818704-fa6b-45c5-89a3-a335b6292ea0}: {Processing response body.}

56028 [pool-1-thread-1] INFO root - {ab818704-fa6b-45c5-89a3-a335b6292ea0}: {Response body was parsed successfully.}

56029 [pool-1-thread-1] INFO root - {ab818704-fa6b-45c5-89a3-a335b6292ea0}: {Operation completed.}

56061 [pool-1-thread-1] INFO root - {ab818704-fa6b-45c5-89a3-a335b6292ea0}: {Starting operation.}

56061 [pool-1-thread-1] INFO root - {ab818704-fa6b-45c5-89a3-a335b6292ea0}: {Starting operation with location 'PRIMARY' per location mode 'PRIMARY_ON`

Any idea what's going on?

Subsequent downloads of CloudBlockBlob fail due to expectedContentLenght=0

When I download CloudBlockBlob object from my store for the first time everything is fine.
On 2nd download it reads all the bytes properly but then it throws exception in the NetworkInputStream class

if (this.bytesRead != this.expectedLength) {
    throw new IOException(SR.CONTENT_LENGTH_MISMATCH);
}

expectedLength is '0' at this point, so I assume it's because it's using cached response on the subsequent calls, but I'm not sure how to disable that (or ignore).
For now I just changed the above line and added this.expectedLength != 0

Azure blob storage setup query

Hey,
I'm new to android development, just wanted to check on how to setup the blob storage sdk. Since it was mentioned in the docs that this has to be done manually. I'm confused on how to obtain the .aar file for the same, I downloaded the azure-core and azure-blob-storage latest release as well but not able to set it up.

Can someone please summarise the steps that need to be taken for setting it up ?

Thanks in advance

Geting a Storage Exception when trying to upload a file

I have a problem while trying to upload a file from my app. I followed this tutorial, but nothing I do seems to work.

Here is my code :

private boolean doFileUpload(String sas) {
        boolean hasFailed = false;
        int i = 0;
        //Attempt 3 times to upload file
        while (!hasFailed) {
            StorageCredentials cred = new StorageCredentialsSharedAccessSignature(sas);
            try {
                String[] split = sas.split("/");
                URI imageUri = new URI((BuildConfig.API_STORAGE_URL + "/" + split[3] + "/" + split[4] + "/" + file.getGuid().toLowerCase() + "." + file.getExtension()).toLowerCase());
                LogUtil.logw(TAG, imageUri);
                CloudBlockBlob blobFromSASCredential = new CloudBlockBlob(imageUri, cred);
                blobFromSASCredential.uploadFromFile(file.getFullFilePath());
                return true;
            } catch (Exception ex) {
                ErrorManager.crash(TAG, ex);
                LogUtil.logw(TAG, file);
                System.gc();
            }

            if (i == 3) {
                hasFailed = true;
            }
            i++;
        }
        return false;
    }

And here is the exception message :

com.microsoft.azure.storage.StorageException: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
            at com.microsoft.azure.storage.core.StorageRequest.materializeException(StorageRequest.java:305)
            at com.microsoft.azure.storage.core.ExecutionEngine.executeWithRetry(ExecutionEngine.java:175)
            at com.microsoft.azure.storage.blob.CloudBlockBlob.uploadFullBlob(CloudBlockBlob.java:826)
            at com.microsoft.azure.storage.blob.CloudBlockBlob.upload(CloudBlockBlob.java:779)
            at com.microsoft.azure.storage.blob.CloudBlob.uploadFromFile(CloudBlob.java:1964)
            at com.microsoft.azure.storage.blob.CloudBlob.uploadFromFile(CloudBlob.java:1936)
            at com.x.y.api.FileUploaderTask.doFileUpload(FileUploaderTask.java:134)

This is driving me pretty nuts, any help would be appreciated...

Thanks !

No Progress info while uploading file to azure blob storage.

Hi,

I am using azure blob storage in my android app to store files.
for uploading the files from android phone to blob storage i am using "CloudBlockBlob" instance
Example:- "cloudBlockBlob.uploadFromFile(File_Path,File_Uri)

issue:
1.i am not able to get upload progress on upload action.
2. if upload fails due to some network issues not able to get the report.
3. no acknowledge report after upload completed.

please help me with this.

Unable to upload to blob error: java.lang.IllegalArgumentException: Address is a relative address. Only absolute addresses are permitted. >>at com.microsoft.azure.storage.StorageUri.AssertAbsoluteUri(StorageUri.java:34) >>at com.microsoft.azure.storage.StorageUri.setPrimaryUri(StorageUri.java:183) >>at com.microsoft.azure.storage.StorageUri.<init>(StorageUri.java:105) at com.microsoft.azure.storage.StorageUri.<init>(StorageUri.java:49) >>at com.microsoft.azure.storage.blob.CloudBlockBlob.<init>(CloudBlockBlob.java:96)

//When I click on the button it called the code below..
// then this launches an intent of file picker..

public void browseFile(View view) {

    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("file/*");
    startActivityForResult(intent, SELECT_PICTURE);

}

//After it calls the on activity result
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    if (resultCode == RESULT_OK) {
        switch (requestCode) {

            case SELECT_PICTURE:

// the filepath is a Uri variable
filepath = getRealPathFromURI(Upload.this, data.getData());
filePath.setText(filepath);

                break;


        }
    }


}

// this method help get the real path
public String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = {MediaStore.Images.Media.DATA};
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}

//then here is the uploading code
public void uploadPhoto(View view) {
if (mClient == null) {
return;
}
linearOverlay.setVisibility(View.VISIBLE);
txt_notifyier.setText("Inserting");
// Create a new item
final Uploads item = new Uploads();
item.setVersion(et_uploadVersion.getText().toString().toLowerCase());
item.setContainerName("todoitemimages");
item.setName(et_uploadName.getText().toString().toLowerCase());
// Use a unigue GUID to avoid collisions.
UUID uuid = UUID.randomUUID();
String uuidInString = uuid.toString();
item.setResourceName(uuidInString);

    ListenableFuture<Uploads> entity = mUploads.insert(item);
    Futures.addCallback(entity, new FutureCallback<Uploads>() {
        @Override
        public void onSuccess(final Uploads result) {

            try {

                et_generatedUploadLink.setText(result.getImageUri());
                // If we have a returned SAS, then upload the blob.
                if (result.getSasQueryString() != null) {

                    // Get the URI generated that contains the SAS
                    // and extract the storage credentials.
                    Thread myThread = new Thread(new Runnable() {

                        @Override
                        public void run() {
                            try {
                                Upload.this.runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        txt_notifyier.setText("Uploading");
                                    }
                                });
                                StorageCredentials cred =
                                        new StorageCredentialsSharedAccessSignature(result.getSasQueryString());
                                URI imageUri = new URI(result.getImageUri());


                                // Upload the new image as a BLOB from a stream.
                                CloudBlockBlob blobFromSASCredential =
                                        new CloudBlockBlob(imageUri, cred);

                                blobFromSASCredential.uploadFromFile(filepath);
                                Upload.this.runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {

                                        txt_notifyier.setText("Finish");
                                        linearOverlay.setVisibility(View.GONE);
                                    }
                                });
                            } catch (final Exception ee) {
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        ee.printStackTrace();
                                        filePath.setText("Message:  " + ee.getMessage() + "\n\n" + "Cause:  " + ee.getCause());
                                        linearOverlay.setVisibility(View.GONE);
                                    }
                                });

                            }

                        }
                    });
                    myThread.start();

                }


            } catch (final Exception e) {
                e.printStackTrace();
                filePath.setText("Message:  " + e.getMessage() + "\n\n" + "Cause:  " + e.getCause());
                linearOverlay.setVisibility(View.GONE);
            }
        }

        @Override
        public void onFailure(Throwable t) {

        }
    });

}

Closeable resource has leak

StrictMode prints warning log on call method container.createIfNotExists()

2020-10-22 18:11:06.983 713-723/? E/StrictMode: A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
java.lang.Throwable: Explicit termination method 'close' not called
at dalvik.system.CloseGuard.open(CloseGuard.java:180)
at java.net.AbstractPlainSocketImpl.create(AbstractPlainSocketImpl.java:103)
at java.net.Socket.createImpl(Socket.java:464)
at java.net.Socket.getImpl(Socket.java:530)
at java.net.Socket.setSoSndTimeout(Socket.java:1194)
at com.android.okhttp.Connection.setTimeouts(Connection.java:508)
at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:400)
at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:130)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:356)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:273)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:478)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:426)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:542)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java)
at com.microsoft.azure.storage.core.ExecutionEngine.executeWithRetry(ExecutionEngine.java:106)
at com.microsoft.azure.storage.blob.CloudBlobContainer.exists(CloudBlobContainer.java:767)
at com.microsoft.azure.storage.blob.CloudBlobContainer.createIfNotExists(CloudBlobContainer.java:377)
at com.microsoft.azure.storage.blob.CloudBlobContainer.createIfNotExists(CloudBlobContainer.java:324)
at com.test.test.repositories.azure.AzureStorageUploadWorker$doWork$2.invokeSuspend(AzureStorageUploadWorker.kt:29)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)

CloudBlobContainer authentication error when repeating listBlobs()

The method CloudBlobContainer.listBlobs() works when called the first time after installing the app, but will not work again and throw the following MAC signature invalid error.

The MAC signature found in the HTTP request 'xxxxxxxxxx' is not the same as any computed signature. Server used following string to sign: 'GET

Mon, 24 Aug 2020 14:39:19 GMT

x-ms-client-request-id:5830d2ce-c356-40c0-a9a1-cecd66921336
x-ms-date:Mon, 24 Aug 2020 16:48:29 GMT
x-ms-version:2017-04-17
/myaccoun t/mycontainer
comp:list
delimiter:/
restype:container'.

The listBlobs() method will only work for the same container again after the app's cache is cleared.

I am using the following code to list blobs (Kotlin)

`
val storageAccount = CloudStorageAccount.parse(connectionString)
val blobClient = storageAccount.createCloudBlobClient()
val container = blobClient.getContainerReference(name)
val blobs = container.listBlobs()

val blobNames: ArrayList = ArrayList()
for (blob in blobs) {
blobNames.add((blob as CloudBlockBlob).name)
}
`

OutOfMemoryError

java.lang.OutOfMemoryError
at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:156)
at java.io.BufferedInputStream.read(BufferedInputStream.java:288)
at com.microsoft.azure.storage.core.Utility.writeToOutputStream(Utility.java:1218)
at com.microsoft.azure.storage.core.Utility.writeToOutputStream(Utility.java:1130)
at com.microsoft.azure.storage.blob.BlobOutputStream.write(BlobOutputStream.java:525)
at com.microsoft.azure.storage.blob.CloudBlockBlob.upload(CloudBlockBlob.java:583)
at com.microsoft.azure.storage.blob.CloudBlob.uploadFromFile(CloudBlob.java:1837)
at com.microsoft.azure.storage.blob.CloudBlob.uploadFromFile(CloudBlob.java:1809)
at com.datatang.client.framework.storage.AzureStorage.uploadFile(AzureStorage.java:135)
at com.datatang.client.framework.upload.service.UploadBinder$2.run(UploadBinder.java:110)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)

Random Non-Fatal Exceptions

Hi,

I am getting random non-fatal exceptions while users try to upload a file to blob.

I am using latest sdk and not able to reproduce it but surely there are daily 30 ~ 50 exceptions are happening out of around 300.

Exceptions are below

Non-fatal Exception: com.microsoft.a.a.ab: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
       at com.microsoft.azure.storage.core.StorageRequest.materializeException(StorageRequest.java:315)
       at com.microsoft.azure.storage.core.ExecutionEngine.executeWithRetry(ExecutionEngine.java:174)
       at com.microsoft.azure.storage.blob.CloudBlockBlob.uploadFullBlob(CloudBlockBlob.java:726)
       at com.microsoft.azure.storage.blob.CloudBlockBlob.upload(CloudBlockBlob.java:679)
       at com.microsoft.azure.storage.blob.CloudBlob.uploadFromFile(CloudBlob.java:1708)
       at com.microsoft.azure.storage.blob.CloudBlob.uploadFromFile(CloudBlob.java:1680)
Non-fatal Exception: com.microsoft.a.a.ab: The server encountered an unknown failure: 
       at com.microsoft.azure.storage.core.ExecutionEngine.executeWithRetry(ExecutionEngine.java:206)
       at com.microsoft.azure.storage.blob.CloudBlobContainer.exists(CloudBlobContainer.java:767)
       at com.microsoft.azure.storage.blob.CloudBlobContainer.createIfNotExists(CloudBlobContainer.java:377)
       at com.microsoft.azure.storage.blob.CloudBlobContainer.createIfNotExists(CloudBlobContainer.java:324)```

Upload status

Is there anyway to get the upload status. We need to find out if the blob is uploaded successfully,

SAS token blob container Shared Key authentication

Hello, I was wondering what are the steps, for using a Share key authentication, instead of providing the account name and key to each user. I am trying to use this library to share files between several users.
Can we have more detailed examples for this situations?

Outdated Sample

Hello, I wanted to ask about why this Android sample is so outdated? Is this SDK no longer supported or is there a more recent sample?

When I try go compile this using the wrapper on the sample project it doesn't seem to work because it says the android gradle plugin version is too old.

In my current Android project we want to upload a set of photos to Azure but I having a tough time finding a good sample that both exemplifies uploading and securing.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.