Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I serve static files from a different URL with Dart?

Tags:

dart

With Dart, I've got awesome.html, but I'd like it to be /awesome. Is this purely an .htaccess (I'm using Apache) thing, or is there a way to go about this the Dart or "modern web development" way?

This .htaccess bit directs /awesome to /awesome.html:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .*[^/]$ %{REQUEST_URI}/ [L,R=301]
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+)/$ $1.html [L]

But then all my relative URL references (to css/js/images) break, and if I rewrite them from "assets/whatever" to "/assets/whatever" it'll break when working in the Dart Editor since it uses URLs like:

http://127.0.0.1:3030/Users/dave/Sites/my-dart-app/web/awesome.html

Ideas? Best practices? Thank you!

like image 721
David Notik Avatar asked Oct 26 '12 06:10

David Notik


2 Answers

thanks for the question!

The answer depends on if you have a proxy or web server in front of your Dart server VM. If you have a proxy in front, then the proxy can do the URL rewriting before the request hits your Dart VM. This is a nice scenario anyway, because a proxy can do caching, SSL, load balancing, and more. The Dart VM is then just an "app server" in this scenario. I would recommend placing an industrial strength web server or proxy in front just as a best practice.

However, if you want to do URL masking and rewriting purely in Dart, here is some code. As Kai says in the comments above, this is generally a framework's job. But I'll include some code here anyway for fun. :)

import 'dart:io';
import 'dart:json';

class StaticFileHandler {
  final String basePath;

  StaticFileHandler(this.basePath);

  _send404(HttpResponse response) {
    response.statusCode = HttpStatus.NOT_FOUND;
    response.outputStream.close();
  }

  String rewritePath(String path) {
    String newPath = path;

    if (path == '/' || path.endsWith('/')) {
      newPath = '${path}index.html'; 
    } else if (!path.endsWith('.html')) {
      newPath = "${path}.html";
    }

    return newPath;
  }

  // TODO: etags, last-modified-since support
  onRequest(HttpRequest request, HttpResponse response) {
    String path = rewritePath(request.path);

    final File file = new File('${basePath}${path}');
    file.exists().then((found) {
      if (found) {
        file.fullPath().then((String fullPath) {
          if (!fullPath.startsWith(basePath)) {
            _send404(response);
          } else {
            file.openInputStream().pipe(response.outputStream);
          }
        });
      } else {
        _send404(response);
      }
    });
  }

}

runServer(String basePath, int port) {
  HttpServer server = new HttpServer();

  server.defaultRequestHandler = new StaticFileHandler(basePath).onRequest;
  server.onError = (error) => print(error);
  server.listen('127.0.0.1', 1337);
  print('listening for connections on $port');
}

main() {
  var script = new File(new Options().script);
  var directory = script.directorySync();
  runServer("${directory.path}", 1337);
}
like image 200
Seth Ladd Avatar answered Oct 24 '22 11:10

Seth Ladd


By the way, I've updated the rewritePath() function in Seth's code some so that it doesn't rewrite assets like .dart and .css files to .html, and so that it works w/ my client-side stuff living in /web.

  String rewritePath(String path) {
    String newPath = path;

    if (path == '/' || path.endsWith('/')) {
      newPath = '/web${path}index.html';
    } else if (!path.endsWith('.html')) {
      if (path.contains('.')) {
        newPath = '/web${path}';
      } else {
        newPath = '/web${path}.html';
      }
    } else {
      newPath = '/web${path}.html';
    }

    //peek into how it's rewriting the paths
    print('$path -> $newPath');

    return newPath;
  }

It's of course super basic, and a framework that handles routing would certainly come in handy (would love to see what you're building @Kai).

like image 23
David Notik Avatar answered Oct 24 '22 10:10

David Notik