runserver.drush.inc

  1. 8.0.x commands/runserver/runserver.drush.inc
  2. 6.x commands/runserver/runserver.drush.inc
  3. 7.x commands/runserver/runserver.drush.inc
  4. 5.x commands/runserver/runserver.drush.inc
  5. master commands/runserver/runserver.drush.inc

Built in http server commands.

Functions

Namesort descending Description
drush_core_runserver Callback for runserver command.
runserver_drush_command Implements hook_drush_command().
runserver_drush_help Implements hook_drush_help().
runserver_parse_uri Parse a URI or partial URI (including just a port, host IP or path).
runserver_uri Determine the URI to use for this server.

File

commands/runserver/runserver.drush.inc
View source
  1. <?php
  2. /**
  3. * @file
  4. * Built in http server commands.
  5. */
  6. /**
  7. * Implements hook_drush_help().
  8. */
  9. function runserver_drush_help($section) {
  10. switch ($section) {
  11. case 'meta:runserver:title':
  12. return dt("Runserver commands");
  13. case 'meta:runserver:summary':
  14. return dt('Launch the built-in PHP webserver.');
  15. case 'drush:runserver':
  16. return dt("Runs a lightweight built in http server for development.
  17. - Don't use this for production, it is neither scalable nor secure for this use.
  18. - If you run multiple servers simultaneously, you will need to assign each a unique port.
  19. - Use Ctrl-C or equivalent to stop the server when complete.");
  20. }
  21. }
  22. /**
  23. * Implements hook_drush_command().
  24. */
  25. function runserver_drush_command() {
  26. $items = array();
  27. $items['runserver'] = array(
  28. 'description' => 'Runs PHP\'s built-in http server for development.',
  29. 'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
  30. 'arguments' => array(
  31. 'addr:port/path' => 'Host IP address and port number to bind to and path to open in web browser. Format is addr:port/path, default 127.0.0.1:8888, all elements optional. See examples for shorthand. Only opens a browser if a path is specified.',
  32. ),
  33. 'options' => array(
  34. 'variables' => 'Key-value array of variables to override in the $conf array for the running site. By default disables drupal_http_request_fails to avoid errors on Windows (which supports only one connection at a time). Comma delimited list of name=value pairs (or array in drushrc).',
  35. 'default-server' => 'A default addr:port/path to use for any values not specified as an argument.',
  36. 'user' => 'If opening a web browser, automatically log in as this user (user ID or username). Default is to log in as uid 1.',
  37. 'browser' => 'If opening a web browser, which browser to user (defaults to operating system default). Use --no-browser to avoid opening a browser.',
  38. 'dns' => 'Resolve hostnames/IPs using DNS/rDNS (if possible) to determine binding IPs and/or human friendly hostnames for URLs and browser.',
  39. ),
  40. 'aliases' => array('rs'),
  41. 'examples' => array(
  42. 'drush rs 8080' => 'Start runserver on 127.0.0.1, port 8080.',
  43. 'drush rs 10.0.0.28:80' => 'Start runserver on 10.0.0.28, port 80.',
  44. 'drush rs [::1]:80' => 'Start runserver on IPv6 localhost ::1, port 80.',
  45. 'drush rs --dns localhost:8888/user' => 'Start runserver on localhost (using rDNS to determine binding IP), port 8888, and open /user in browser.',
  46. 'drush rs /' => 'Start runserver on default IP/port (127.0.0.1, port 8888), and open / in browser.',
  47. 'drush rs --default-server=127.0.0.1:8080/ -' => 'Use a default (would be specified in your drushrc) that starts runserver on port 8080, and opens a browser to the front page. Set path to a single hyphen path in argument to prevent opening browser for this session.',
  48. 'drush rs :9000/admin' => 'Start runserver on 127.0.0.1, port 9000, and open /admin in browser. Note that you need a colon when you specify port and path, but no IP.',
  49. ),
  50. );
  51. return $items;
  52. }
  53. /**
  54. * Callback for runserver command.
  55. */
  56. function drush_core_runserver($uri = NULL) {
  57. global $user, $base_url;
  58. // Determine active configuration.
  59. $uri = runserver_uri($uri);
  60. if (!$uri) {
  61. return FALSE;
  62. }
  63. // Remove any leading slashes from the path, since that is what url() expects.
  64. $path = ltrim($uri['path'], '/');
  65. // $uri['addr'] is a special field set by runserver_uri()
  66. $hostname = $uri['host'];
  67. $addr = $uri['addr'];
  68. drush_set_context('DRUSH_URI', 'http://' . $hostname . ':' . $uri['port']);
  69. // We pass in the currently logged in user (if set via the --user option),
  70. // which will automatically log this user in the browser during the first
  71. // request.
  72. if (drush_get_option('user', FALSE) === FALSE) {
  73. drush_set_option('user', 1);
  74. }
  75. drush_bootstrap_max(DRUSH_BOOTSTRAP_DRUPAL_LOGIN);
  76. // We delete any registered files here, since they are not caught by Ctrl-C.
  77. _drush_delete_registered_files();
  78. // We set the effective base_url, since we have now detected the current site,
  79. // and need to ensure generated URLs point to our runserver host.
  80. // We also pass in the effective base_url to our auto_prepend_script via the
  81. // CGI environment. This allows Drupal to generate working URLs to this http
  82. // server, whilst finding the correct multisite from the HTTP_HOST header.
  83. $base_url = 'http://' . $addr . ':' . $uri['port'];
  84. $env['RUNSERVER_BASE_URL'] = $base_url;
  85. // We pass in an array of $conf overrides using the same approach.
  86. // This is available as an option for developers to pass in their own
  87. // favorite $conf overrides (e.g. disabling css aggregation).
  88. $current_override = drush_get_option_list('variables', array());
  89. $override = array();
  90. foreach ($current_override as $name => $value) {
  91. if (is_numeric($name) && (strpos($value, '=') !== FALSE)) {
  92. list($name, $value) = explode('=', $value, 2);
  93. }
  94. $override[$name] = $value;
  95. }
  96. $env['RUNSERVER_CONF'] = urlencode(serialize($override));
  97. // We log in with the specified user ID (if set) via the password reset URL.
  98. $user_message = '';
  99. $usersingle = drush_user_get_class()->getCurrentUserAsSingle();
  100. if ($usersingle->id()) {
  101. $browse = $usersingle->passResetUrl($path);
  102. $user_message = ', logged in as ' . $usersingle->getUsername();
  103. }
  104. else {
  105. $browse = drush_url($path);
  106. }
  107. drush_print(dt('HTTP server listening on !addr, port !port (see http://!hostname:!port/!path), serving site !site!user...', array('!addr' => $addr, '!hostname' => $hostname, '!port' => $uri['port'], '!path' => $path, '!site' => drush_get_context('DRUSH_DRUPAL_SITE', 'default'), '!user' => $user_message)));
  108. // Start php 5.4 builtin server.
  109. // Store data used by runserver-prepend.php in the shell environment.
  110. foreach ($env as $key => $value) {
  111. putenv($key . '=' . $value);
  112. }
  113. if (!empty($uri['path'])) {
  114. // Start a browser if desired. Include a 2 second delay to allow the
  115. // server to come up.
  116. drush_start_browser($browse, 2);
  117. }
  118. // Start the server using 'php -S'.
  119. $php = drush_get_option('php', 'php');
  120. if (drush_drupal_major_version() >=8) {
  121. $extra = ' "' . __DIR__ . '/d8-rs-router.php"';
  122. }
  123. else {
  124. $extra = ' --define auto_prepend_file="' . __DIR__ . '/runserver-prepend.php"';
  125. }
  126. drush_shell_exec_interactive($php . ' -S ' . $addr . ':' . $uri['port'] . $extra);
  127. }
  128. /**
  129. * Determine the URI to use for this server.
  130. */
  131. function runserver_uri($uri) {
  132. $drush_default = array(
  133. 'host' => '127.0.0.1',
  134. 'port' => '8888',
  135. 'path' => '',
  136. );
  137. $user_default = runserver_parse_uri(drush_get_option('default-server', ''));
  138. $site_default = runserver_parse_uri(drush_get_option('uri', ''));
  139. $uri = runserver_parse_uri($uri);
  140. if (is_array($uri)) {
  141. // Populate defaults.
  142. $uri = $uri + $user_default + $site_default + $drush_default;
  143. if (ltrim($uri['path'], '/') == '-') {
  144. // Allow a path of a single hyphen to clear a default path.
  145. $uri['path'] = '';
  146. }
  147. // Determine and set the new URI.
  148. $uri['addr'] = $uri['host'];
  149. if (drush_get_option('dns', FALSE)) {
  150. if (ip2long($uri['host'])) {
  151. $uri['host'] = gethostbyaddr($uri['host']);
  152. }
  153. else {
  154. $uri['addr'] = gethostbyname($uri['host']);
  155. }
  156. }
  157. }
  158. return $uri;
  159. }
  160. /**
  161. * Parse a URI or partial URI (including just a port, host IP or path).
  162. *
  163. * @param string $uri
  164. * String that can contain partial URI.
  165. *
  166. * @return array
  167. * URI array as returned by parse_url.
  168. */
  169. function runserver_parse_uri($uri) {
  170. if (empty($uri)) {
  171. return array();
  172. }
  173. if ($uri[0] == ':') {
  174. // ':port/path' shorthand, insert a placeholder hostname to allow parsing.
  175. $uri = 'placeholder-hostname' . $uri;
  176. }
  177. // FILTER_VALIDATE_IP expects '[' and ']' to be removed from IPv6 addresses.
  178. // We check for colon from the right, since IPv6 addresses contain colons.
  179. $to_path = trim(substr($uri, 0, strpos($uri, '/')), '[]');
  180. $to_port = trim(substr($uri, 0, strrpos($uri, ':')), '[]');
  181. if (filter_var(trim($uri, '[]'), FILTER_VALIDATE_IP) || filter_var($to_path, FILTER_VALIDATE_IP) || filter_var($to_port, FILTER_VALIDATE_IP)) {
  182. // 'IP', 'IP/path' or 'IP:port' shorthand, insert a schema to allow parsing.
  183. $uri = 'http://' . $uri;
  184. }
  185. $uri = parse_url($uri);
  186. if (empty($uri)) {
  187. return drush_set_error('RUNSERVER_INVALID_ADDRPORT', dt('Invalid argument - should be in the "host:port/path" format, numeric (port only) or non-numeric (path only).'));
  188. }
  189. if (count($uri) == 1 && isset($uri['path'])) {
  190. if (is_numeric($uri['path'])) {
  191. // Port only shorthand.
  192. $uri['port'] = $uri['path'];
  193. unset($uri['path']);
  194. }
  195. }
  196. if (isset($uri['host']) && $uri['host'] == 'placeholder-hostname') {
  197. unset($uri['host']);
  198. }
  199. return $uri;
  200. }