Skip to content

Commit 527c1ab

Browse files
committed
Use a default generated handler URL
1 parent 3051de9 commit 527c1ab

File tree

8 files changed

+87
-26
lines changed

8 files changed

+87
-26
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,13 @@ Now that the package is installed, the final step is to set the correct environm
7878

7979
Please check the table below on what the values mean and what their value should be.
8080

81-
|Environment variable| Description |Example
82-
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---
83-
|`STACKKIT_CLOUD_TASKS_PROJECT`| The project your queue belongs to. |`my-project`
84-
|`STACKKIT_CLOUD_TASKS_LOCATION`| The region where the AppEngine is hosted |`europe-west6`
85-
|`STACKKIT_CLOUD_TASKS_HANDLER`| The URL that Cloud Tasks will call to process a job. This should be the URL to your Laravel app with the `handle-task` path added |`https://<your website>.com/handle-task`
86-
|`STACKKIT_CLOUD_TASKS_QUEUE`| The queue a job will be added to |`emails`
87-
|`STACKKIT_CLOUD_TASKS_SERVICE_EMAIL`| The email address of the AppEngine service account. Important, it should have the correct roles. See the section below which roles. |`[email protected].com`
81+
| Environment variable | Description |Example
82+
--------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---
83+
| `STACKKIT_CLOUD_TASKS_PROJECT` | The project your queue belongs to. |`my-project`
84+
| `STACKKIT_CLOUD_TASKS_LOCATION` | The region where the AppEngine is hosted |`europe-west6`
85+
| `STACKKIT_CLOUD_TASKS_QUEUE` | The queue a job will be added to |`emails`
86+
| `STACKKIT_CLOUD_TASKS_SERVICE_EMAIL` | The email address of the AppEngine service account. Important, it should have the correct roles. See the section below which roles. |`[email protected]`
87+
| `STACKKIT_CLOUD_TASKS_HANDLER` (optional) | The URL that Cloud Tasks will call to process a job. This should be the URL to your Laravel app with the `handle-task` path added. By default we will use the URL that dispatched the job. |`https://<your website>.com/handle-task`
8888
</details>
8989
<details>
9090
<summary>

src/CloudTasksConnector.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@ public function connect(array $config)
1111
{
1212
Config::validate($config);
1313

14+
// The handler is the URL which Cloud Tasks will call with the job payload. This
15+
// URL of the handler can be manually set through an environment variable, but
16+
// if it is not then we will choose a sensible default (the current app url)
17+
if (empty($config['handler'])) {
18+
// At this point (during service provider boot) the trusted proxy middleware
19+
// has not been set up, and so we are not ready to get the scheme and host
20+
// So we wrap it and get it later, after the middleware has been set up.
21+
$config['handler'] = function () {
22+
return request()->getSchemeAndHttpHost();
23+
};
24+
}
25+
1426
return new CloudTasksQueue($config, app(CloudTasksClient::class));
1527
}
1628
}

src/CloudTasksQueue.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ protected function pushToCloudTasks($queue, $payload, $delay = 0)
100100
$availableAt = $this->availableAt($delay);
101101

102102
$httpRequest = $this->createHttpRequest();
103-
$httpRequest->setUrl($this->config['handler']);
103+
$httpRequest->setUrl(Config::getHandler($this->config['handler']));
104104
$httpRequest->setHttpMethod(HttpMethod::POST);
105105
$httpRequest->setBody(
106106
// Laravel 7+ jobs have a uuid, but Laravel 6 doesn't have it.

src/CloudTasksServiceProvider.php

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,21 @@
77
use Illuminate\Queue\Events\JobFailed;
88
use Illuminate\Queue\Events\JobProcessed;
99
use Illuminate\Queue\Events\JobProcessing;
10-
use Illuminate\Queue\QueueManager;
11-
use Illuminate\Routing\Router;
1210
use Illuminate\Support\ServiceProvider as LaravelServiceProvider;
1311
use function Safe\file_get_contents;
1412
use function Safe\json_decode;
1513

1614
class CloudTasksServiceProvider extends LaravelServiceProvider
1715
{
18-
public function boot(QueueManager $queue, Router $router): void
16+
public function boot(): void
1917
{
2018
$this->registerClient();
21-
$this->registerConnector($queue);
19+
$this->registerConnector();
2220
$this->registerConfig();
2321
$this->registerViews();
2422
$this->registerAssets();
2523
$this->registerMigrations();
26-
$this->registerRoutes($router);
24+
$this->registerRoutes();
2725
$this->registerDashboard();
2826
}
2927

@@ -37,8 +35,13 @@ private function registerClient(): void
3735
$this->app->bind('cloud-tasks-api', CloudTasksApiConcrete::class);
3836
}
3937

40-
private function registerConnector(QueueManager $queue): void
38+
private function registerConnector(): void
4139
{
40+
/**
41+
* @var \Illuminate\Queue\QueueManager $queue
42+
*/
43+
$queue = $this->app['queue'];
44+
4245
$queue->addConnector('cloudtasks', function () {
4346
return new CloudTasksConnector;
4447
});
@@ -85,8 +88,13 @@ private function registerMigrations(): void
8588
]);
8689
}
8790

88-
private function registerRoutes(Router $router): void
91+
private function registerRoutes(): void
8992
{
93+
/**
94+
* @var \Illuminate\Routing\Router $router
95+
*/
96+
$router = $this->app['router'];
97+
9098
$router->post('handle-task', [TaskHandler::class, 'handle'])->name('cloud-tasks.handle-task');
9199

92100
if (CloudTasks::dashboardDisabled()) {

src/Config.php

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
namespace Stackkit\LaravelGoogleCloudTasksQueue;
44

5+
use Closure;
56
use Error;
7+
use Exception;
8+
use Safe\Exceptions\UrlException;
69

710
class Config
811
{
@@ -16,12 +19,55 @@ public static function validate(array $config): void
1619
throw new Error(Errors::invalidLocation());
1720
}
1821

19-
if (empty($config['handler'])) {
20-
throw new Error(Errors::invalidHandler());
21-
}
22-
2322
if (empty($config['service_account_email'])) {
2423
throw new Error(Errors::invalidServiceAccountEmail());
2524
}
2625
}
26+
27+
/**
28+
* @param Closure|string $handler
29+
*/
30+
public static function getHandler($handler): string
31+
{
32+
$handler = value($handler);
33+
34+
try {
35+
$parse = \Safe\parse_url($handler);
36+
37+
if (empty($parse['host'])) {
38+
throw new UrlException();
39+
}
40+
41+
// A mistake which can unknowingly be made is that the task handler URL is
42+
// (still) set to localhost. That will never work because Cloud Tasks
43+
// should always call a public address / hostname to process tasks.
44+
if (in_array($parse['host'], ['localhost', '127.0.0.1', '::1'])) {
45+
throw new Exception(sprintf(
46+
'Unable to push task to Cloud Tasks because the handler URL is set to a local host: %s. ' .
47+
'This does not work because Google is not able to call the given local URL. ' .
48+
'If you are developing on locally, consider using Ngrok or Expose for Laravel to expose your local ' .
49+
'application to the internet.',
50+
$handler
51+
));
52+
}
53+
54+
// Versions 1.x and 2.x required the full path (e.g. my-app.com/handle-task). In 3.x and beyond
55+
// it is no longer necessary to also include the path and simply setting the handler
56+
// URL is enough. If someone upgrades and forgets we will warn them here.
57+
if (!empty($parse['path'])) {
58+
throw new Exception(
59+
'Unable to push task to Cloud Tasks because the task handler URL (' . $handler . ') is not ' .
60+
'compatible. To fix this, please remove \'' . $parse['path'] . '\' from the URL, ' .
61+
'or copy from here: STACKKIT_CLOUD_TASKS_HANDLER=' . $parse['scheme'] . '://' . $parse['host']
62+
);
63+
}
64+
65+
return $handler . '/handle-task';
66+
} catch (UrlException $e) {
67+
throw new Exception(
68+
'Unable to push task to Cloud Tasks because the task handler URL (' . $handler . ') is ' .
69+
'malformed. Please inspect the URL closely for any mistakes.'
70+
);
71+
}
72+
}
2773
}

src/Errors.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,6 @@ public static function invalidLocation(): string
1414
return 'Google Cloud Tasks location not provided. To fix this, set the STACKKIT_CLOUD_TASKS_LOCATION environment variable';
1515
}
1616

17-
public static function invalidHandler(): string
18-
{
19-
return 'Google Cloud Tasks handler not provided. To fix this, set the STACKKIT_CLOUD_TASKS_HANDLER environment variable';
20-
}
21-
2217
public static function invalidServiceAccountEmail(): string
2318
{
2419
return 'Google Service Account email address not provided. This is needed to secure the handler so it is only accessible by Google. To fix this, set the STACKKIT_CLOUD_TASKS_SERVICE_EMAIL environment variable';

src/TaskHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ private function loadQueueConnectionConfiguration(array $task): void
5757
* @var stdClass $command
5858
*/
5959
$command = unserialize($task['data']['command']);
60-
$connection = $command->command ?? config('queue.default');
60+
$connection = $command->connection ?? config('queue.default');
6161
$this->config = array_merge(
6262
(array) config("queue.connections.{$connection}"),
6363
['connection' => $connection]

tests/ConfigTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public function location_is_required()
3131
}
3232

3333
/** @test */
34-
public function handler_is_required()
34+
public function there_is_a_sensible_handler_default()
3535
{
3636
$this->setConfigValue('handler', '');
3737

0 commit comments

Comments
 (0)