node-solid-server icon indicating copy to clipboard operation
node-solid-server copied to clipboard

Malformed uri:s on Windows

Open highlevellogic opened this issue 4 years ago • 69 comments

Windows 10, NSS v5.5.6

Added a Trusted App via the data browser and that resulted in a modified card$.ttl file with malformed URI:s such as:

pim:preferencesFile
    <https://rogerfgay.solid.hll.nu:7443%2Fprofile%2Fcard//settings/prefs.ttl>;

Since I'm stuck on Windows, I don't mind trying to fix this, but I'm still a bit of a newbie and would appreciate being pointed to the parts of NSS that are likely to be where the problem is.

highlevellogic avatar Dec 03 '20 13:12 highlevellogic

You could have a look to request/sharingRequest

bourgeoa avatar Dec 03 '20 13:12 bourgeoa

resource-mapper, line 87

pathname.split(pathUtil.sep).map((component) => encodeURIComponent(component)).join('/')

Does anyone know why the component should be URI encoded? This is where forward slashes are replaced by %2F.

highlevellogic avatar Dec 04 '20 10:12 highlevellogic

@highlevellogic this is based on the URL specification https://www.w3.org/Addressing/URL/url-spec.txt and https://www.w3.org/Addressing/URL/url-spec.txt

On the other side files are not limited to ascii To preserve compatibility the only way to resolve that is encode/decode components when going file <--> URI resource.

bourgeoa avatar Dec 04 '20 11:12 bourgeoa

Shouldn't it be encodeURI() instead of encodeURIComponent()? That would preserve the forward slashes.

I'm using ASCII so did a simple test by not encoding. The problem described here goes away then.

highlevellogic avatar Dec 04 '20 11:12 highlevellogic

Using encodeURI(), I just added https://шеллы.example.net as a trusted app without problem. It appears in card$.ttl exactly as https://шеллы.example.net Nothing else is malformed as in the first post. Still has relative path for preference and index files.

highlevellogic avatar Dec 04 '20 11:12 highlevellogic

Tangent: Please don't use somewhere.be or the like (which might exist, now or in the past or future) where example.be (which should never exist) is appropriate. (See RFC6761.)

TallTed avatar Dec 04 '20 14:12 TallTed

Alternatively, trying to see this as a Windows only problem ... just replace pathUtil.sep with '/' :) pathname.split('/').map((component) => encodeURIComponent(component)).join('/')

But I still don't know why there's any need to encode normal URI components such as / and : and ? etc.

highlevellogic avatar Dec 04 '20 15:12 highlevellogic

Alternatively, trying to see this as a Windows only problem ... just replace pathUtil.sep with '/' :)

But is a windows only because all pod are actually created and working on multiple servers.

You do not encode / because you use pathname.split('/').

bourgeoa avatar Dec 04 '20 15:12 bourgeoa

Yes. Explicit use of '/' works for Windows too whereas pathUtil.sep (\ on Windows) doesn't.

I'm still wondering about the first solution though. I don't see why encodeURIComponent() is appropriate. Why encode basic parts of URI:s such as / , :, ?, and so on?

Here's a point that may make my questions seem less confusing. I was getting / converted to %2F .... would that ever make sense? (regardless of os)

Using '/' instead of pathUtil.sep is a Windows only solution. But is it the right one?

highlevellogic avatar Dec 04 '20 16:12 highlevellogic

What would be wrong with doing it like this? (os independet)

pathname.split('/').map((component) => encodeURI(component)).join('/')

highlevellogic avatar Dec 04 '20 17:12 highlevellogic

As I can see by googling this is a strong recommendation https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent

bourgeoa avatar Dec 04 '20 20:12 bourgeoa

How is this lesser? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI

highlevellogic avatar Dec 04 '20 20:12 highlevellogic

I'm sorry I am not a coder can't help you more.

Have you now a working solution for windows. Are your changes only in resource mapper.js ?

bourgeoa avatar Dec 04 '20 20:12 bourgeoa

Yes. I can get it to work with only changes is resource mapper. I'm still a newbie but trying to extend my concern to the overall project, I think the questions I'm raising now have to do with striking the right chord with standards.

Aside from that, I'll probably spend the weekend working with aplications I'm trying to build. Hope to have one or two open-sourced next week.

highlevellogic avatar Dec 04 '20 21:12 highlevellogic

The data browser seems to work pretty well now on Windows. I've submitted PR #1535

highlevellogic avatar Dec 05 '20 12:12 highlevellogic

My curiosity about this line of code hasn't died. I've even been looking at various uri schemes. It would be more efficient to use: encodeURI(pathname).join('/') rather than pathname.split(pathUtil.sep).map((component) => encodeURIComponent(component)).join('/') So long as the result is correct for all cases. I don't see why it wouldn't be.

highlevellogic avatar Dec 05 '20 14:12 highlevellogic

I created a pod in your server and true it seems to work quite well with the dataBrowser and solid-ide creating folder, files, managing acl, zip/unzip ... That's a wonderful improvement.

The only bug found is creating chat either from any folder or from profile/card#me returns 500 What NSS version are you using ? Your server says v5.5.2 ? Sorry just checked a header, in fact you are running v5.5.6 May be you could try v5.6.0 to see if the 500 error is still there.

bourgeoa avatar Dec 05 '20 14:12 bourgeoa

Thank you. Now running v5.6.0

highlevellogic avatar Dec 05 '20 15:12 highlevellogic

Do I need to do anything to enable websockets?

highlevellogic avatar Dec 05 '20 15:12 highlevellogic

Path must start with hostname (/bourgeoa.solid.hll.nu)

did you change anything ?

Do I need to do anything to enable websockets?

not to my knowledge

bourgeoa avatar Dec 05 '20 15:12 bourgeoa

Path must start with hostname (/bourgeoa.solid.hll.nu)

did you change anything ?

Oops! Little mistake when I upgraded. Fixed it. It's correct in my fork - i.e. before the PR.

highlevellogic avatar Dec 06 '20 08:12 highlevellogic

As follow up to path.sep v / noticed fetch of data/solid.hll.nu/index.html has a rootPath with back slashes. I believe that console log is from line 406 in lib/ldp.js The read doesn't go through resource-mapper. But because JavaScript adapts automatically it still works.

highlevellogic avatar Dec 06 '20 08:12 highlevellogic

@prefix : <#>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix solid: <http://www.w3.org/ns/solid/terms#>.
@prefix foaf: <http://xmlns.com/foaf/0.1/>.
@prefix pim: <http://www.w3.org/ns/pim/space#>.
@prefix pro: <./>.
@prefix n0: <http://www.w3.org/ns/auth/acl#>.
@prefix inbox: </inbox/>.
@prefix bou: </>.
@prefix n: <http://www.w3.org/2006/vcard/ns#>.
@prefix schem: <http://schema.org/>.

pro:card a foaf:PersonalProfileDocument; foaf:maker :me; foaf:primaryTopic :me.

:me
    a schem:Person, foaf:Person;
    n:fn "Alain Bourgeois";
    n:organization-name "individuel";
    n:url
            [
                a n:WebID;
                n:value "https://bourgeoa.solidcommunity.net/profile/card#me"
            ];
    n0:trustedApp
            [
                n0:mode n0:Append, n0:Control, n0:Read, n0:Write;
                n0:origin <https://jeff-zucker.github.io>
            ],
            [
                n0:mode n0:Append, n0:Control, n0:Read, n0:Write;
                n0:origin <https://solidcommunity.net>
            ],
            [
                n0:mode n0:Append, n0:Control, n0:Read, n0:Write;
                n0:origin <https://www.bourgeoa.ga>
            ];
    ldp:inbox inbox:;
    pim:preferencesFile </settings/prefs.ttl>;
    pim:storage bou:;
    solid:account bou:;
    solid:privateTypeIndex </settings/privateTypeIndex.ttl>;
    solid:publicTypeIndex </settings/publicTypeIndex.ttl>;
    foaf:name "Alain Bourgeois".

highlevellogic avatar Dec 06 '20 08:12 highlevellogic

Are you adding the port number when trying to create a new directory?

solid:handlers PUT -- Error creating directory: Error: Path contains invalid characters: C:/programs/solid/data/bourgeoa.solid.hll.nu/IndividualChats/bourgeoa.solid.hll.nu:7443

It got created anyway: C:\programs\solid\data\bourgeoa.solid.hll.nu\IndividualChats\bourgeoa.solid.hll.nu%3A7443

You also have: C:\programs\solid\data\bourgeoa.solid.hll.nu\IndividualChats%3A7443

highlevellogic avatar Dec 06 '20 11:12 highlevellogic

The only bug found is creating chat either from any folder or from profile/card#me returns 500

Yes I was diving to this problem. Chat is not working because of the path name used which is the pod name that includes the port.

This an incompatibility to resolve with mashlib or resource-mapper.js

bourgeoa avatar Dec 06 '20 12:12 bourgeoa

: is reserved in Windows .. not allowed in directory / filenames. It's explicitely dealt with in /node-modules/fs-extra/lib/mkdirs/make-dir.js

const checkPath = pth => {
  if (process.platform === 'win32') {
    const pathHasInvalidWinCharacters = /[<>:"|?*]/.test(pth.replace(path.parse(pth).root, ''))

    if (pathHasInvalidWinCharacters) {
      const error = new Error(`Path contains invalid characters: ${pth}`)
      error.code = 'EINVAL'
      throw error
    }
  }
}

(I guess that was your point. This isn't where to fix it. :)

highlevellogic avatar Dec 06 '20 12:12 highlevellogic

Is %encode/decode depending on the os a solution ? I think the solution should not impact the actual Pod's on Linux.

If you try it I could go on further testings.

bourgeoa avatar Dec 06 '20 13:12 bourgeoa

Windows disallows a different set of characters for directory / filenames. Colon is not allowed.

As workaround, I'm thinking I should set this up to run on port 443. Then we should have WebID:s etc. without port number ... am I right? Should chat work then?

Quick try and there's some confusion about the validity of my certificates. It might be tomorrow before I have it sorted.

Oddly enough, 7443 still works. Certbot complained that the certificates are still good.

highlevellogic avatar Dec 06 '20 13:12 highlevellogic

It needs to work with any port so a solution is for windows os to convert path colon to %3A and reverse to build URI

bourgeoa avatar Dec 06 '20 14:12 bourgeoa

It needs to work with any port so a solution is for windows os to convert path colon to %3A and reverse to build URI

Understood. But that seems like another problem. Am I correct that the current system just wants to use : because that works on Linux? (As you were able to create directories with %3A). To get it to work with any port on Windows would then mean fundamentally changing something in Solid. I'd have to start by finding out where in the code to address it and then sell the idea that I'm breaking things for the sake of Windows. (Unless I can be too clever :)

At this point, if testing can be concluded on what's been done already, that would be a plus. Then maybe I can look into the next step if I can figure out where in the code to address it.

highlevellogic avatar Dec 06 '20 14:12 highlevellogic