forked from damsfx/valet-windows
-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathShareTool.php
More file actions
144 lines (123 loc) · 3.54 KB
/
Copy pathShareTool.php
File metadata and controls
144 lines (123 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
<?php
namespace Valet\ShareTools;
use Valet\CommandLine;
use Valet\Filesystem;
use Exception;
use DomainException;
use GuzzleHttp\Client;
use function Valet\retry;
use function Valet\info;
abstract class ShareTool {
/**
* @var CommandLine
*/
protected $cli;
/**
* @var Filesystem
*/
protected $files;
/**
* @var array
*/
protected $tunnelsEndpoints = [
'http://127.0.0.1:4040/api/tunnels',
'http://127.0.0.1:4041/api/tunnels'
];
/**
* Create a new instance.
*
* @param CommandLine $cli
* @param Filesystem $files
*/
public function __construct(CommandLine $cli, Filesystem $files) {
$this->cli = $cli;
$this->files = $files;
}
/**
* Start sharing.
*
* @param string $site The site
* @param int $port The site's port
* @param array $options Options/flags to pass to ngrok
*/
abstract public function start(string $site, int $port, array $options = []);
/**
* Run CLI commands
*
* @param string $command
*/
abstract public function run(string $command);
/**
* Get the config path.
*
* @return string The path.
*/
abstract public function getConfig();
/*--------------------------------------------------------*
* Fully declared methods that don't need to be abstracts *
*--------------------------------------------------------*/
/**
* Get the current tunnel URL from the API.
*
* @param string $site The site that is being shared.
*
* @return string The current tunnel URL
*/
public function currentTunnelUrl(string $site) {
info("Trying to retrieve tunnel URL for '$site'...");
foreach ($this->tunnelsEndpoints as $endpoint) {
try {
$response = retry(5, function () use ($endpoint, $site) {
// Create a GuzzleHttp get request to the ngrok tunnels API and
// get the body of the API response and decode the json.
$body = json_decode((new Client())->get($endpoint)->getBody());
// If tunnels is set in the body AND has more than 0 tunnels...
if (isset($body->tunnels) && count($body->tunnels) > 0) {
// If the tunnel URL is NOT null, return the URL.
if ($tunnelUrl = $this->findHttpTunnelUrl($body->tunnels, $site)) {
$this->copyUrlToClipboard($tunnelUrl);
return $tunnelUrl;
}
}
throw new DomainException("Failed to retrieve tunnel URL for '$site'.");
}, 250);
// If response is NOT empty, return the response.
if (! empty($response)) {
return $response;
}
}
catch (Exception $e) {
// Do nothing, suppress the exception to check the other port
}
}
throw new DomainException("Tunnel not established for '$site'.");
}
/**
* Find the HTTP tunnel URL from the list of tunnels.
*
* @param array $tunnels The list of tunnels.
* @param string|null $site The site that is being shared.
*
* @return string|null
*/
public function findHttpTunnelUrl(array $tunnels, ?string $site = null) {
// If there are active tunnels on the ngrok instance we will spin through them and
// find the one responding on HTTP. Each tunnel has an HTTP and a HTTPS address
// but for local dev purposes we just desire the plain HTTP URL endpoint.
foreach ($tunnels as $tunnel) {
if (($tunnel->proto === 'http' || $tunnel->proto === 'https') && strpos($tunnel->config->addr, $site)) {
return $tunnel->public_url;
}
}
return null;
}
/**
* Copy the public URL to the clipboard.
*
* @param string $url The public URL to copy.
*/
public function copyUrlToClipboard(string $url) {
$this->cli->passthru("echo $url | clip");
info("It has been copied to your clipboard.");
}
}