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

Store method doesn't work (returns 404) #677

Open
zaminhub opened this issue Feb 5, 2024 · 4 comments
Open

Store method doesn't work (returns 404) #677

zaminhub opened this issue Feb 5, 2024 · 4 comments

Comments

@zaminhub
Copy link

zaminhub commented Feb 5, 2024

Stack Laravel 10.43 + Jetstream v4.22 (inertia v0.6.11 + vue v3.2.31). php v8.1
After clockwork package installed the store methods of any resourse controller doesn't work and returns 404 page not found response.
After removing clockwork package the problem disappears.
I suppose this is because headers which should be "Accept: application/json", but I am not sure. Somehow clockwork package does remove this header from all post requests, but not from put/patch request.

@itsgoingd
Copy link
Owner

Hey, I can't see any weird behavior with a new Laravel + Jetstream installation. Can you share a simple repo demonstrating this issue?

@zaminhub
Copy link
Author

Sorry for late response. Here is demo repo https://github.com/zaminhub/jetstream.test.git
cloclwork installed store method doesn't work.

@zaminhub
Copy link
Author

Hello @itsgoingd Did you check the demo repo above?

@itsgoingd
Copy link
Owner

Hey, sorry, forgot about this one, thanks for reminding me. Turns out this is quite a convoluted issue. I will try to explain.

The code that triggers this behavior is this line in your javascript code:

https://github.com/zaminhub/jetstream.test/blob/master/resources/js/Pages/Posts/PostModal.vue#L19

This ends up sending a POST request with an empty _method override when trying to create new posts. When editing existing posts, the override is set to PUT, making it work.

On server-side, Clockwork checks the method of the incoming request, very early in the processing. To do so, we call $request->getMethod(), which is a method from the underlying Symfony HTTP request implementation. This method does a bunch of things, resolves the base request method, tries to apply various types of overrides and validates the result.

Since your app is sending request with an empty _method override, the method executes all the way up to the following validation step, which fails (since $method is an empty string) and an exception is thrown. I assume since this is very early in the request processing, the exception ends up being interpreted as 404 error (haven't looked into this part that much).

https://github.com/symfony/http-foundation/blob/7.1/Request.php#L1166-L1168

Well, a good question is, why does this work without Clockwork?

Turns out, Laravel includes a middleware, that replaces empty strings in the request by nulls. Now when we call the same getMethod() method, we will hit this early return and never reach the exception part.

https://github.com/symfony/http-foundation/blob/7.1/Request.php#L1156-L1158

The issue with Clockwork installed is the execution order, which looks like this:

Request is received
Clockwork calls getMethod() // _method is empty string and exception is thrown
ConvertEmptyStringsToNull middleware is ran
Routing calls getMethod() // _method is null now, so the call defaults to POST

TL;DR I'm not sure if or how we want to fix this in Clockwork, but you can trivially fix this on your side, by adding POST as default value to _method, or not including that key at all.

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

No branches or pull requests

2 participants