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

Override third party libraries to check for filename casing #28

Merged
merged 4 commits into from
Feb 15, 2018

Conversation

Hemant-Mann
Copy link
Collaborator

Fix for #27

I have modified the League\Util\ContentListingFormatter class which checks whether the file is a part of the current directory or not.

The checks are done based on the property OCA\Files_external_dropbox\Storage::isCaseInsensitiveStorage

Copy link
Contributor

@PVince81 PVince81 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks fine.

@SergioBertolinSG can you test if that works correctly with all operations ? I think we used to have unit tests that you can run against your own account, but need to be run manually.

@Hemant-Mann
Copy link
Collaborator Author

Added some comments in code

@Hemant-Mann Hemant-Mann changed the base branch from master to release/1.0.1 January 10, 2018 12:33
@SergioBertolinSG
Copy link

OK now it is keeping the filenames coming from dropbox backend, good. But files/folder uploaded to OC are still being lowercased. (It requires some refreshes to see it).

@Hemant-Mann
Copy link
Collaborator Author

OK now it is keeping the filenames coming from dropbox backend, good. But files/folder uploaded to OC are still being lowercased. (It requires some refreshes to see it).

I have removed that code which was converting paths to lowercase

@SergioBertolinSG
Copy link

SergioBertolinSG commented Jan 10, 2018

Ok the main issue works fine now.

I have observed that uploading a file changing the case of some characters in the filename leads to a weird dialog comparing with all the files in the folder:

screen shot 2018-01-10 at 17 20 49

Also both files appear in the folder. After a refresh only the last one appears.

@Hemant-Mann
Copy link
Collaborator Author

Hemant-Mann commented Jan 10, 2018

I have observed that uploading a file changing the case of some characters in the filename leads to a weird dialog comparing with all the files in the folder:

No idea why this is happening

@SergioBertolinSG
Copy link

Yes, this behaviour happens always, the conflict shows some random info when uploading the same file with different cases.

To reproduce:

  1. Upload a file called for example bigHamster.jpg.
  2. Rename in your filesystem the file to BigHamster.jpg.
  3. Upload the same file with different name now (BigHamster.jpg).

Result:

screen shot 2018-01-10 at 18 06 48

@PVince81 what should be the right behaviour here? no conflict at all? Uploading directly? (it is the same file after all).

@SergioBertolinSG
Copy link

SergioBertolinSG commented Jan 10, 2018

Renaming to a different case returns a warning:

The name "perrito.jpg" is already used in the folder "/DropboxAPINUEVA/MAYUSCULAS2". Please choose a different name.

Steps to reproduce:

  1. Upload a file for example perrito.jpg.
  2. Rename it to a different case combination for example PERRITO.jpg.
  3. See the warning and refresh the page.

And it leads to duplicated files. The old filename only existing in owncloud, not in dropbox.

screen shot 2018-01-10 at 18 19 09

@PVince81
Copy link
Contributor

@SergioBertolinSG how do other case insensitive storages behave like SMB ? if they have the same issue then please ignore until we sort out these scenarios.

cc @jvillafanez

@jvillafanez
Copy link
Member

Regarding SMB, uploading "FilE.txt" stores the file in SMB with the same case, and returns the file with the same case. The problem is that for SMB "FilE.txt" is the same that "file.txt" and "File.txt", so when if you have uploaded "FilE.txt" and check if "file.txt" exists, SMB says that the file exists.

Storing the file is case-sensitive but the filename comparison is case-insensitive. I think this sums up more or less what's happening with SMB.

@SergioBertolinSG
Copy link

@Hemant-Mann the behaviour should be the same as in SMB.

@Hemant-Mann
Copy link
Collaborator Author

Yes @SergioBertolinSG The same is the case for Dropbox

Storing the file is case-sensitive but the filename comparison is case-insensitive

@SergioBertolinSG
Copy link

This #28 (comment) and #28 (comment)

Should be addressed to merge this.

@Hemant-Mann
Copy link
Collaborator Author

@PVince81 Could you give a hint as to where should I look in code to address @SergioBertolinSG #28 (comment) ?

@PVince81
Copy link
Contributor

I don't know sorry, would need to step with a debugger.

@PVince81
Copy link
Contributor

@Hemant-Mann can you step there with a debugger ?

@Hemant-Mann
Copy link
Collaborator Author

Yeah will do
Last week was little busy

@Hemant-Mann
Copy link
Collaborator Author

Okay so I understood a few things
First of all consider I have the following file structure for Dropbox

DropboxV2/
├── Foo
│   └── bar
└── contacts.json

2 directories, 1 file

Now I try to upload this file ContacTs.json I get error from server
====> Response Headers

Request URL:http://localhost:8181/owncloud/remote.php/webdav/DropboxV2/ContacTs.json
Request Method:PUT
Status Code:412 Precondition failed
Remote Address:[::1]:8181
Referrer Policy:no-referrer

===> Response Body

<?xml version="1.0" encoding="utf-8"?>
<d:error xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">
  <s:exception>Sabre\DAV\Exception\PreconditionFailed</s:exception>
  <s:message>An If-None-Match header was specified, but the ETag matched (or * was specified).</s:message>
  <s:header>If-None-Match</s:header>
</d:error>

So I put a breakpoint in frontend JS as well
https://github.com/owncloud/core/blob/master/apps/files/js/file-upload.js#L1063 (showConflict function is called)

Inside that function we try to find more info about the conflicting file here
https://github.com/owncloud/core/blob/master/apps/files/js/file-upload.js#L604
And this is where the problem is

conflict_dialog_box

So the function getFullPath is returning /DropboxV2 instead of /DropboxV2/ContacTs.json so backend is returning the INFO for the parent directory instead of the file ContacTs.json

Here are the 2 consequents AJAX requests sent to the server
ajax_requests

@Hemant-Mann
Copy link
Collaborator Author

Also found 2 more things

  1. Slowness is because calls of the function file_exists are not cached. I did not do this last time as it was interfering with upload process (Will open a PR to fix this)

  2. Fixing of file name cases opened a new issue which is: duplicate files inserted in oc_filecache
    Consider the above example ContacTs.json was not found in cache but dropbox returned that the file exists so cache was updated by inserting a new row for this file here
    https://github.com/owncloud/core/blob/master/lib/private/Files/Cache/Scanner.php#L208
    As mentioned by @SergioBertolinSG here Override third party libraries to check for filename casing #28 (comment)

@PVince81 PVince81 mentioned this pull request Jan 29, 2018
@Hemant-Mann
Copy link
Collaborator Author

Hemant-Mann commented Jan 29, 2018

@PVince81 any ideas on how to fix the different file name issue in oc_filecache?

This is where data is fetched for ContacTs.json https://github.com/owncloud/core/blob/master/lib/private/Files/Cache/Scanner.php#L149

so $file = 'ContacTs.json and $data is what returned by lib/private/Files/Storage/Common.php::getMetaData

Checked in Debugger

@Hemant-Mann
Copy link
Collaborator Author

Hemant-Mann commented Jan 29, 2018

Correction this PR does not introduce this bug

As mentioned by @SergioBertolinSG here #28 (comment)

Behaviour is the same with master branch I checked

From what I have seen in the code, I guess this should be a problem for all case insensitive storage

Consider the $internalPath = 'Foo.txt' and a file foo.txt exists in external storage then
https://github.com/owncloud/core/blob/master/lib/private/Files/View.php#L1364
will say file exists and correspondingly cache will be updated follow these

  1. https://github.com/owncloud/core/blob/master/lib/private/Files/View.php#L1369
  2. https://github.com/owncloud/core/blob/master/lib/private/Files/Cache/Scanner.php#L311
  3. https://github.com/owncloud/core/blob/master/lib/private/Files/Cache/Scanner.php#L149
  4. https://github.com/owncloud/core/blob/master/lib/private/Files/Cache/Scanner.php#L208 (where $file = 'Foo.txt', $data = (array) $fileId = -1)

@jvillafanez
Copy link
Member

As long as the behaviour is acceptable and ownCloud doesn't do weird things, I'd just return whatever Dropbox is doing. If you have contacts.json and Dropbox says that contacTs.json exists, then just go with it.

As far as I know, there are only a couple of problematic behaviours: uploading a file with the same name but different casing and renaming a file with different casing. If ownCloud just rejects both operations, I think it's fine as long as the users know this.

@Hemant-Mann
Copy link
Collaborator Author

If you have contacts.json and Dropbox says that contacTs.json exists, then just go with it.

Yes this is the current behaviour

But a new file contacTs.json is added in oc_filecache and as a result 2 files are displayed in folder listing
I think this is what @SergioBertolinSG is pointing out

@Hemant-Mann
Copy link
Collaborator Author

So should we merge this?

@PVince81
Copy link
Contributor

PVince81 commented Feb 1, 2018

maybe we need a more generic solution in general when dealing with any kind of case insensitive storages: owncloud/core#17161. From @jvillafanez's research this is not easy to achieve.

If this PR makes Dropbox works a little better then let's merge it as a step forward.

* This property is used to check whether the storage is case insensitive or not
* @var boolean
*/
protected $isCaseInsensitiveStorage = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tabs vs. spaces -> please unify

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay let me correct this

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@patrickjahns I checked in the editor it is indented using Tabs only
the diff is because previously this block was indented using tab size: 2 whereas the whole file was indented using tab size: 4

@patrickjahns patrickjahns changed the base branch from release/1.0.1 to master February 5, 2018 20:00
@patrickjahns patrickjahns added this to the development milestone Feb 5, 2018
@patrickjahns
Copy link
Contributor

Moved to development and adjusted base branch

@Hemant-Mann Hemant-Mann mentioned this pull request Feb 9, 2018
11 tasks
@Hemant-Mann
Copy link
Collaborator Author

Merge this?

@patrickjahns
Copy link
Contributor

@SergioBertolinSG
You had a look at this - what was the latest testing results with this PR ?

@SergioBertolinSG
Copy link

#27 is fixed here but
#28 (comment) and #28 (comment) are introduced.

Which is a different behaviour than WND.

@Hemant-Mann
Copy link
Collaborator Author

@SergioBertolinSG
As I have pointed out in various comments this PR does not introduce these

#28 (comment) and #28 (comment) are introduced.

You can verify with master branch the behaviour is the same. Both of your comments can be reproduced easily

a) Regarding the incorrect conflict dialog box it related to file-upload.js in ownCloud core. I have mentioned the details here #28 (comment)

b) Regarding duplicate file issue #28 (comment) it is also related to ownCloud core @PVince81 have mentioned here #28 (comment) (This behaviour should be easily reproduced with other case insensitive storages)

@SergioBertolinSG
Copy link

@Hemant-Mann Ok I have check those using current master and you are right.

So lets merge this and open separated issues about them.

@patrickjahns patrickjahns merged commit 6a9d236 into master Feb 15, 2018
@patrickjahns
Copy link
Contributor

@SergioBertolinSG
please create respective issues

@patrickjahns patrickjahns deleted the file_names_case branch February 15, 2018 10:15
@SergioBertolinSG
Copy link

Opened here:

Renaming of files to a different case leads to file duplication. #33

Files conflict dialog is not prepared to deal with case-sensitive storages.
(This one affects all case-sensitive storages)
owncloud/core#30502

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants