-
Notifications
You must be signed in to change notification settings - Fork 8
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
file mode validation cannot be implemented according to PSR-17 #42
Conversation
the psr-17 spec requires to have different exceptions for invalid modes and other file opening errors: ``` @throws \RuntimeException If the file cannot be opened. @throws \InvalidArgumentException If the mode is invalid. ``` How is it expected to be implemented? I can't figure out a way to implement this because the accepted modes depend on the OS. And the error message that are returned also depend on the OS. See https://github.com/guzzle/psr7/pull/274/files#r291236165 On travis for example it say `No such file or directory` although the mode is wrong. So we cannot distinguish between wrong mode or a different failure unless we hardcode the modes. But that would be pointless and would also be against the PSR-17 spec which says it must accept anything that `fopen` can accept. So it can't be hardcoded. Diactoros also does not seem to implement this behavior. So did anybody find a solution or is the spec not implementable? Response from Woody Gilk > yeah that is really bad on our part, i think you should just ignore `InvalidArgumentException` and only deal with `RuntimeException` the `InvalidArgumentException` was intended for packages that *want* to validate the mode > for instance, if a StreamFactory only wanted to support readable streams, it has the option to throw `InvalidArgumentException` for any mode that is not `$mode = 'r'`
It can specifically be hard-coded, because that is exactly what PHP does. They do a very straight-forward check on modes, and also seem to do this without caring about the filesystem it is running on: switch (mode[0]) {
case 'r':
flags = 0;
break;
case 'w':
flags = O_TRUNC|O_CREAT;
break;
case 'a':
flags = O_CREAT|O_APPEND;
break;
case 'x':
flags = O_CREAT|O_EXCL;
break;
case 'c':
flags = O_CREAT;
break;
default:
/* unknown mode */
return FAILURE;
} If your PSR-17 implementation uses $resource = @\fopen($filename, $mode);
if (false === $resource) {
if (0 === \strlen($mode) || false === \in_array($mode[0], ['r', 'w', 'a', 'x', 'c'])) {
throw new \InvalidArgumentException('The mode '.$mode.' is invalid.');
} Of course if your implementation is not using I am open for comments as to why this would not be a solution. But I fully believe the spec to be implementable as I did for Nyholm/psr7. As such, I would be against this proposed change to the tests. |
this is now tested in the interop factory tests ref. http-interop/http-factory-tests#42
@Zegnat thanks for the pointer. I've used your suggestion to make Guzzle pass the tests. But I don't think it's a good idea to require PSR-17 implementation to basically depend on an implementation detail in PHP. Either the spec is self-contained and lists the valid modes itself, or it forwards to php fopen but then shouldn't require validation in the spec. |
I left this PR open for several days to allow for additional comments. None received, so I am merging. Thanks @Tobion . |
Released in version 0.6.0. |
the psr-17 spec requires to have different exceptions for invalid modes and other file opening errors:
How is it expected to be implemented? I can't figure out a way to implement this because the accepted modes depend on the OS. And the error message that are returned also depend on the OS. See https://github.com/guzzle/psr7/pull/274/files#r291236165
On travis for example it say
No such file or directory
although the mode is wrong. So we cannot distinguish between wrong mode or a different failure unless we hardcode the modes. But that would be pointless and would also be against the PSR-17 spec which says it must accept anything thatfopen
can accept. So it can't be hardcoded.Diactoros also does not seem to implement this behavior. So did anybody find a solution or is the spec not implementable?
Response from Woody Gilk