Hi I'm trying to create a web app where you can access files on a system through a web browser. The web app structure looks like this:
commander
cmdr
packages
lib
cmdr.dart
gui
packages
web
assets
css
console.dart
editor.dart
client.dart
explorer.dart
index.html
cmdr.dart is the server and I initiate the http_server to host index.html on there. The index pulls the client.dart file as a script. The editor.dart, console.dart and explorer.dart files are all part of the client file.
The problem is when I run the http_server to host index.html, it doesn't access the client files. Most of the dependencies aren't pulled except for the CSS files. Furthermore I thought maybe compiling into javascript would solve this issue as it would pull all the code together into one file. However the same issue exists where the HTML gets put together but none of the client components are created.
My server code is as follows:
// Setting up Virtual Directory
VirtualDirectory virDir;
void directoryHandler(dir, request) {
var indexUri = new Uri.file(dir.path).resolve('index.html');
virDir.serveFile(new File(indexUri.toFilePath()), request);
}
void main(List<String> args) {
// Set default dir as current working directory.
Directory dir = Directory.current;
// Creating Virtual Directory
virDir = new VirtualDirectory(Platform.script.resolve('/Users/donghuynh/git/commander/gui/web').toFilePath())
..allowDirectoryListing = true
..directoryHandler = directoryHandler
..followLinks = true;
// Set up logging.
log = new Logger('server');
Logger.root.onRecord.listen(new SyncFileLoggingHandler("server.log"));
// Create an args parser to override the workspace directory if one is supplied.
var parser = new ArgParser();
parser.addOption('directory', abbr: 'd', defaultsTo: Directory.current.toString(), callback: (directory) {
dir = new Directory(directory);
});
parser.parse(args);
// Initialize the DirectoryWatcher.
watcher = new DirectoryWatcher(dir.path);
// Set up an HTTP webserver and listen for standard page requests or upgraded
// [WebSocket] requests.
HttpServer.bind(InternetAddress.ANY_IP_V4, 8080).then((HttpServer server) {
log.info("HttpServer listening on port:${server.port}...");
server.listen((HttpRequest request) {
// WebSocket requests are considered "upgraded" HTTP requests.
if (WebSocketTransformer.isUpgradeRequest(request)) {
log.info("Upgraded ${request.method} request for: ${request.uri.path}");
WebSocketTransformer.upgrade(request).then((WebSocket ws) {
handleWebSocket(ws, dir);
});
} else {
log.info("Regular ${request.method} request for: ${request.uri.path}");
// TODO: serve regular HTTP requests such as GET pages, etc.
virDir.serveRequest(request);
}
});
});
}
Acessing index.html through a web browser I get these errors:
http://localhost:8080/packages/bootjack/css/bootstrap.min.css Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/packages/ace/src/js/ext-language_tools.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/packages/ace/src/js/ace.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/packages/browser/dart.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/packages/bootjack/css/bootstrap.min.css Failed to load resource: the server responded with a status of 404 (Not Found)
The files actually exist in those locations (though sym linked) but they are not being pulled for some reason.
-Don
As far as I remember you need to pass an additional argument to VirtualDirectory to follow symlinks.
You shoud'nt serve Dart source directly anyway but instead the output from pub build (at least for production). For development, forwarding requests to a running pub serve instance is probably the better and also the officially suggested way.
Related
We are using connexion to serve the swagger ui. We are using the openapi 3.0.0 specification. Here is a small part of our swagger.yml:
openapi: 3.0.0
servers:
- url: /
paths:
/resource:
...
/resource2:
...
in this case the ui is served at /ui. We are however using nginx to redirect all requests to /resource into this container. We would like swagger-ui to be served at /some-subdir/ui instead of at /ui, in order to be able to redirect the requests to the right container.
trial 1
openapi: 3.0.0
servers:
- url: /app
paths:
/resource:
...
/resource2:
...
which works, except that the resources are now served at /app/resource etc, while the same resource might in the future be served by another app, so we don't want the app name to appear in the URL of the resources (while it might be acceptable just for the swagger-ui).
trial 2
I found that, when constructing the connexion app, I could specify the swagger_url option:
options = {
'swagger_url': '/app/ui'
}
connexion_app = connexion.App(__name__, specification_dir='./', options=options)
now the swagger-ui is served at /app/ui, but the ui is trying to serve /openapi.json which is not reachable since not under /app (or any other subdir).
Almost there, there is another (well hidden) option to change the path to the openapi.json, the combination with swagger_url works:
options = {
'swagger_url': '/app/ui',
'openapi_spec_path': '/app/openapi.json'
}
connexion_app = connexion.App(__name__, specification_dir='./', options=options)
I am trying to read server file in javascript in ruby on rails project.
$.ajax({
url: "/public/uploads/goodj.json",
success: function (file_content) {
console.log(file_content);
}
});
And this causes error
GET http://localhost:3000/public/uploads/goodj.json 404 (Not Found)
I think server is recognizing this request as action of controller.
What can I do to make server to understand this is request for reading file?
From Rails guides:
config.public_file_server.enabled configures Rails to serve static
files from the public directory. This option defaults to true, but in
the production environment it is set to false because the server
software (e.g. NGINX or Apache) used to run the application should
serve static files instead. If you are running or testing your app in
production mode using WEBrick (it is not recommended to use WEBrick in
production) set the option to true. Otherwise, you won't be able to
use page caching and request for files that exist under the public
directory.
And the URL should be /uploads/goodj.json, not /public/uploads/goodj.json. So the code snippet should look like that:
$.ajax({
url: "/uploads/goodj.json",
success: function (file_content) {
console.log(file_content);
}
});
In my project, I've a JS file that I've included in the index file at the top of the page. The file contains collection of common jquery functions for events, e.g.:
$('#student').click(function () {
var url = "../Layout/EditStudent?StdID=" + $(this).attr('data-sid') + '&crsID=' + $(this).attr('data-crsID');
console.info(url);
window.location.href = url;
});
When I publish the application to IIS, the application along with the buttons works fine. However, when I debug the application in Visual Studio (which to my understanding spawns a local IIS/ IIS-Express instance), buttons don't work and in browser's console window, I can see the error:
500 Internal Server Error.
After checking the server logs, I can see the following warning:
ModuleName IIS Web Core
Notification AUTHENTICATE_REQUEST
HttpStatus 500
HttpReason Internal Server Error
HttpSubStatus 0
ErrorCode Either a required impersonation level was not provided, or the provided impersonation level is invalid. (0x80070542)
What am I doing wrong?
I've written a Grails application that connects to S3 and streams a file back to the client. This has worked great so far, up until I've tried to use it to download a large (2GB) file. I see the following behaviour:
When starting the download normally by calling the controller, after around 1GB, the download 'completes'.
Opening multiple tabs to trigger several simultaneous downloads causes the downloads to 'complete' after a few MB, although the actual amount downloaded seems to be random each time. This can also be observed when performing simultaneous downloads on multiple machines.
In both cases, the error messages are the same:
errors.GrailsExceptionResolver SocketException occurred when processing request: [GET] /download
Connection reset.:
java.net.SocketException: Connection reset
errors.GrailsExceptionResolver IllegalStateException occurred when processing request: [GET] /download
getOutputStream() has already been called for this response.
Here's the part of the controller concerned with the download:
DownloadController.groovy
def index() {
def fileStream = s3Service.getStream()
response.setHeader("Content-disposition", "attachment;filename=foo.csv")
response.contentType = "text/csv"
response.outputStream = fileStream
response.outputStream.flush()
}
..and a snippet of the service that connects to S3 and gets the file:
S3Service.groovy
def getStream() {
def outputStream = ""
try {
AmazonS3 s3 = new AmazonS3Client()
S3Object object = s3.getObject(new GetObjectRequest('my-bucket-name', 'path/to/file.csv'))
outputStream = object.getObjectContent()
}
catch (AmazonServiceException ase) {
/* Log the error. Omitted for brevity. */
}
catch (AmazonClientException ase) {
/* Log the error. Omitted for brevity. */
}
return outputStream
}
I'm really stumped as to what's causing this.
It turns out that this error was occurring because the app is running on a server behind a load balancer, which is attempting to cache files that pass through it. It's unable to cache the larger files as it has limited disk space, and the download fails.
This was verified by connecting an instance of the app running locally to AWS, and observing that the strange behaviour no longer occurs.
d3.csv("result.csv", function(flights) {
var nestByDate = d3.nest()
.key(function(d) { return d3.time.day(d.date); });
..........
When I am trying to run above d3.js code from web server then it executes d3.js properly by loading csv file.
but when I am trying to run d3.js as shown below,
d3.csv("D:\\Project Space\\D3Demo\\WebContent\\result.csv", function(flights) {
var nestByDate = d3.nest()
.key(function(d) { return d3.time.day(d.date); });
..........
then it shows following error:
XMLHttpRequest cannot load file:///D:/Project%20Space/D3Demo/WebContent/result.csv. Cross origin requests are only supported for HTTP`
How to solve this problem ?
There is no way to solve the problem using D3's convenience functions.
d3.csv fundamentally is an AJAX request and is beholden to the same-origin policy.
When you load the file location, your browser realizes that the requested file does not exist on the same domain (likely localhost in your case) and prevents the request from completing.
A simple way to get around this would be to simply serve the content over localhost or whatever you are using.
Alternatively you can look in to Cross-origin Resource Sharing, or for better compatibility: JSONP. In both of these cases you will likely have to roll your own function to convert the CSV data into a javascript array.