My First Pull Request to Laravel Framework — Part 2
Check this article on Medium: @ngodingbang/my-first-pull-request-to-laravel-framework-part-2-888d06ed86f3
You may want to read this article in Bahasa Indonesia version: Pull Request Pertama Saya di Laravel Framework — Part 2
What Exactly Was the Bug I Found?
Basically, I’m trying to add a request header when sending an HTTP Request using the HTTP Client feature in Laravel. But using the withHeaders()
method to add a request header in this case is impossible because I need to add the request header in a dynamic way that relies on the URL address of the HTTP Request underlying with.
So I decided to use the provided beforeSending()
method and added the request header by creating a callback as the code shown below.
I can’t use the withHeaders()
method of the Illuminate\Http\Client\PendingRequest $pendingRequest
parameter to add any new request header.
$pendingRequest->withHeaders([‘Authorization’ => ‘Bearer ‘.$requestLine]);
This things happened because the $pendingRequest
parameter is already instantiated before HTTP::beforeSending()
method is called, so using withHeader()
method in the $pendingRequest
parameter is useless. The only way to add the wanted request header into the HTTP Client above is to use the withHeader()
method provided by the Illuminate\Http\Client\Request $request
parameter.
$request->toPsrRequest()->withHeader(‘Authorization’, ‘Bearer ‘.$requestLine);
When we use HTTP::beforeSending()
, what actually happens is that the previously created callback will be registered into the property in the PendingRequest
class as follows.
Then all of the registered callbacks will be executed using the PendingRequest
class’s runBeforeSendingCallbacks()
method as follows.
This is where the problem starts to happen. When using the above method, the request header does not change at all. I keep trying with the code I created, but it still does not give me any significant changes. The request header that I added in the previous callback is still not being sent to the HTTP Client.
Then How Do I Solve The Bug?
At first I did not understand why this could happen. But after digging further, I finally found where this problem begins. It turns out that the runBeforeSendingCallbacks()
method in the PendingRequest
class that is used to run HTTP::beforeSending()
doesn’t work as expected. Finally I tried to tweak the code in the PendingRequest
class as follows.
So from these tweaks, there are some changes that I made:
@return
of the method I changed from\Closure
to\GuzzleHttp\Psr7\RequestInterface
. This doesn’t actually have a direct impact on the code, but it’s clear from the documentation point of view that@return
’s data type is incorrect. Because thetap()
method used to modify the$request
variable should return the$request
itself which is\GuzzleHttp\Psr7\RequestInterface
(More explanation can be read here: @taylorotwell/tap-tap-tap-1fc6fc1f93a6).- I created a new variable
$callbackResult
to capture the result of the pre-existingcall_user_func()
method. So if there is a return value given from the execution of thecall_user_func()
method, then the return value will be assigned to the$request
variable. - Then I changed the
$request
variable in thetap()
andeach()
method to pass by reference so that the changes made by$callbackResult
can be passed to the return value of therunBeforeSendingCallbacks()
method itself.
From these changes, the request header that I added to the previous callback can finally be sent to the HTTP Client as I wanted. Of course there is a slight adjustment to the callback that is in Http::beforeSending()
as follows.
Now What?
After going so many road to resolve this, it’s time to submit this bugfix to Laravel. But it seems the story doesn’t fit if I put everything in this part, so I decided to separate it in the next chapter.
My First Pull Request to Laravel Framework — Part 3
For those of you who want to know or trying to make a pull request to Laravel, let’s have a look on that one. Thank you for reading and see you in the next part! Arigatou 🙏