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

Shared Link for a docx/xlsx file cannot be downloaded #105

Closed
thekindJose opened this Issue Sep 23, 2016 · 10 comments

Comments

Projects
None yet
4 participants
@thekindJose

thekindJose commented Sep 23, 2016

Hi, I'm using the onedrive api explorer to get familiar with how to use it and I've run into the following problem:
When I create a link to share a docx or an xlsx file, and send the link to someone, it directly opens the browser to view the file. But when I create a link for a png file, the link shared allows the person who receives the link to download it.
If I try to download the link generated for a docx/xlsx file within a sample app which uses the android download manager there is an error which does not let me to download it.
Any clue about what to do to be able to download the docx/xlsx file using the shared link?
Thanks!

@peternied peternied added bug question and removed bug labels Sep 23, 2016

@peternied

This comment has been minimized.

Contributor

peternied commented Sep 23, 2016

Related: OneDrive/onedrive-explorer-android#75

The format of URLs that OneDrive returns are not always in a pattern that work for the Android Download manager, this 'limited' behavior is documented degree here http://www.digiblog.de/2011/04/android-and-the-download-file-headers/

In order to avoid this issue you can use a getContent() request to download the file bytes and put them where desired, see how the OneDrive Explorer Android does this in its DisplayItem.java@91.

InputStream in = null;
try {
    in = oneDriveClient()
            .getDrive()
            .getItems(mId)
            .getContent()
            .buildRequest()
            .get();
} catch (...) {
    // Handle errors
}
// Use `in` stream to place the file contents where desired.
@thekindJose

This comment has been minimized.

thekindJose commented Sep 23, 2016

Hi again,
thanks for your response. Maybe I have not explained myself properly, but the issue I want to point is not with Android Download Manager.
For instance, if you generate a shared link for a PPTX with the explorer api sample and send it via email to someone, if he clicks on the link from a computer, instead of downloading the file (which is what I'm looking for), the browser is opened and Powerpoint online displays the file.
If you follow the same steps for a ZIP file, and click on the link sent via email, the file is downloaded (which is what I need).
What I'm looking for is the "direct link" concept.
Thanks.

@peternied

This comment has been minimized.

Contributor

peternied commented Sep 23, 2016

Thanks for the clarification, you can do this with a little bit of legwork

Once you've created a link, you'll have a webUrl in the response:

webUrl=https://1drv.ms/w/s!Am4TRnwGUV3agjGHlTbRZjEovdTt

If you just query this link, you'll get a 301 message which should redirect you to a url like so:

https://onedrive.live.com/redir?resid=DA5D51067C46136E!305&authkey=!AIeVNtFmMSi91O0&ithint=file%2cdocx

If you replace the redir part of the path to download this modified link will download the file.

For some additional background on what you can do with sharing links see https://dev.onedrive.com/shares/shares.htm

@thekindJose

This comment has been minimized.

thekindJose commented Sep 26, 2016

Hi @peternied , thanks for the help, but I'm having some issues with this:

  • Using the OneDriveSDKSample, in ItemFragment.java, I'm creating the link as follows:
               application.getOneDriveClient()
                                .getDrive()
                                .getItems(item.id)
                                .getCreateLink(items[selection.get()].toString())
                                .buildRequest()
                                .create(new DefaultCallback<Permission>(getActivity()) {
                                    @Override
                                    public void success(final Permission permission) {
                                        new Thread(new Runnable() {
                                            @Override
                                            public void run() {
                                                try {
                                                    URL url = new URL(permission.link.webUrl);
                                                    Log.d("OneDriveSDK", "> link.WebUrl: " + permission.link.webUrl);
                                                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                                                    int responseCode = connection.getResponseCode();
                                                    InputStream inputStream = connection.getInputStream();
                                                    URL newURL = connection.getURL();
                                                    Log.d("OneDriveSDK", "> responseCode: " + responseCode);
                                                    Log.d("OneDriveSDK", "> newURL: " + newURL);
                                                    inputStream.close();
                                                } catch (IOException e) {
                                                    e.printStackTrace();
                                                }
                                            }
                                        }).start();
  • I'm selecting a file from my SharePoint and output from code above is the following:
09-26 11:59:13.677 2146-4585/com.microsoft.onedrive.onedriveapiexplorer D/OneDriveSDK: > link.WebUrl: https://displaynote-my.sharepoint.com/personal/jose_alvarez_displaynote_com/_layouts/15/guestaccess.aspx?guestaccesstoken=7QtonBoEEjrqquXT6GGbwK2tROXknxj1JT0M4r6QXSs%3d&docid=0c449c3eed7f34e2ea7ce1b03d35a1b66&rev=1
09-26 11:59:14.594 2146-4585/com.microsoft.onedrive.onedriveapiexplorer D/OneDriveSDK: > responseCode: 200
09-26 11:59:14.595 2146-4585/com.microsoft.onedrive.onedriveapiexplorer D/OneDriveSDK: > newURL: https://displaynote-my.sharepoint.com/personal/jose_alvarez_displaynote_com/_layouts/15/WopiFrame.aspx?guestaccesstoken=y%2f7NYN8avgYBNzR0YbC7d0eOXTI1V3i%2f0BQ4SKzccsA%3d&docid=0c449c3eed7f34e2ea7ce1b03d35a1b66&action=view
  • But still the file cannot be downloaded if I perform the steps I mentioned you in previous comment: grab new link, send it via email and open from browser. Still when you click on the link the file is opened on browser with office online instead of downloaded.
    If you look at returned status code, is returning 200.
    Any clue what can be the issue?
@ginesguiropa

This comment has been minimized.

ginesguiropa commented Oct 3, 2016

I have the same problem. The docx, pptx, xlsx... documents can't be downloaded directly when i get the public link.

@peternied

This comment has been minimized.

Contributor

peternied commented Oct 5, 2016

@daboxu It looks like we need a solution for downloading from sharing links via ODB, can you provide instructions for that?

@daboxu

This comment has been minimized.

Contributor

daboxu commented Oct 5, 2016

one possible approach is using our /shares API for ODB. The link "permission.link.webUrl" actually could be encode into a share key by:

shareId = "u!" + urlfriendly(base64encode(permission.link.webUrl))

after we got the shareId, you can compose a request to /shares API to get the content:

        BaseApplication app = ((BaseApplication) activity.getApplication());
        app.getOneDriveClient().getExecutors().performOnBackground(new Runnable() {
            @Override
            public void run() {

                IOneDriveClient client = ((BaseApplication) activity.getApplication()).getOneDriveClient();
                String request = client.getShare(shareId).getRequestUrlWithAdditionalSegment("/root/content");

                 // remove "/me" part of the serviceRoot because /shares does not exist under /me
                if (((BaseApplication) activity.getApplication()).getOneDriveClient().getAuthenticator().getAccountInfo().getServiceRoot().endsWith("/me")) {
                    request = request.replaceFirst("/me", "");
                }

               // append access token
                request += ("?access_token=" + client.getAuthenticator().getAccountInfo().getAccessToken());

                try {
                    URL contentUrl = new URL(request);
                    HttpURLConnection connection = (HttpURLConnection) contentUrl.openConnection();
                    int responseCode = connection.getResponseCode();
                    InputStream inputStream = connection.getInputStream();
                    BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
                    String line;
                    while ((line = br.readLine()) != null) {
                        Log.d("Custom", line);
                    }
                    inputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

while this approache you need not only the link, but also a valid access token which I believe you will have if you already allow user grant it to you

@daboxu

This comment has been minimized.

Contributor

daboxu commented Oct 17, 2016

hi @thekindJose @ginesguirpa, have you found the way for the problem?

@thekindJose

This comment has been minimized.

thekindJose commented Oct 20, 2016

Hi @daboxu. No, I haven't found how to do what I need.
Not sure if I have understood you properly, but with your proposal users who receive shared link will need to use the Microsoft API and have a valid token. Please correct me if I'm wrong.
If you read whole post, what I actually need is to generate a link for a file, which can be shared to a user via email (for instance) and user can download the file by using the link even from a computer without the need of using any Microsoft office account/api. To be clear, without any restriction, I need the "direct link" flavour.
It's working fine for a zip file for instance, probably because Microsoft cannot open it, so it allows to download the file. But for a word file, Office Online is opened in the browser when clicking on the link. What I need is the same than with a zip file.
Hope you can point me into the right direction.
Thanks!

@daboxu

This comment has been minimized.

Contributor

daboxu commented Oct 21, 2016

hi @thekindJose , sorry misunderstood your scenario. Unfortunately right now we don't support downloading office documents via a sharing link but thanks for the suggestion and it indeed is a good feature. Please go to http://onedrive.uservoice.com/ to post it so that other can vote on it as well.

@daboxu daboxu closed this Oct 24, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment