root-project / jsroot

JavaScript ROOT
MIT License
187 stars 80 forks source link

Server response size XXX larger than expected YYY Abort I/O operation #188

Closed DraTeots closed 5 years ago

DraTeots commented 5 years ago

When opening a file with a setup, which is pretty much from the examples:

http://localhost:8888/static/jsroot/index.htm?file=name.root

I see this in a console:

Server response size 204215 larger than expected 7619 Abort I/O operation

And loading large files takes a long time

More on setup:

First thing I checked that Ranges work on the server:

curl -I http://localhost:8888/rjs/data/data.root
...
Accept-Ranges: bytes
Content-Length: 204215
curl http://localhost:8888/rjs/data/data.root -i -H "Range: bytes=0-1023"
HTTP/1.1 206 Partial Content
Server: TornadoServer/6.0.3
Content-Type: application/octet-stream
...
Accept-Ranges: bytes
Content-Range: bytes 0-1023/204215
Content-Length: 1024

<bytes>

Large files actually get loaded fast (which means, partial content is utilized) if I use "select file" button in the simple GUI.

index.html is from jsroot

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <title>Read a ROOT file</title>
      <link rel="shortcut icon" href="img/RootIcon.ico"/>
      <script type="text/javascript" src="scripts/JSRootCore.js?gui"></script>
   </head>
   <body>
      <div id="simpleGUI" path="../files/" files="ct.root;exclusion.root;fillrandom.root;glbox.root;graph.root;hsimple.root;legends.root;rf107.root;stacks.root;zdemo.root">
         loading scripts ...
      </div>
   </body>
</html>

I can provide a docker file with the setup.

linev commented 5 years ago

I can provide a docker file with the setup.

It should be enough to have ROOT file which makes the problem. Do you have an example?

DraTeots commented 5 years ago

Any of these https://gitlab.com/eic/epw/tree/master/data

e.g.

beagle_events.root

You should be able to download them right from the page

linev commented 5 years ago

Seems to be, you have problem with HTTP server. It returns complete file instead of requested potion of data. If your file sizes not that big, you can load complete content at once:

http://localhost:8888/static/jsroot/index.htm?file=name.root+
linev commented 5 years ago

File is working without problem:

http://jsroot.gsi.de/dev/?file=../files/tmp/beagle_events.root&item=events/tree;1&opt=ntracks_b

Seems to be, it is your server limitation

linev commented 5 years ago

If I do request to Apache server, I see different headers:

curl http://jsroot.gsi.de/files/tmp/beagle_events.root   -i -H "Range: bytes=0-1023" 

HTTP/1.1 206 Partial Content
Date: Tue, 13 Aug 2019 14:56:29 GMT
Server: Apache/2.2
Last-Modified: Tue, 13 Aug 2019 14:46:52 GMT
ETag: "70051d47-524682-59000b60e716d"
Accept-Ranges: bytes
Content-Length: 1024
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: range
Access-Control-Expose-Headers: content-range,content-length,content-type,accept-ranges
Access-Control-Allow-Methods: HEAD,GET
Content-Range: bytes 0-1023/5392002
Content-Type: text/plain

Warning: Binary output can mess up your terminal. Use "--output -" to tell 
Warning: curl to output it to your terminal anyway, or consider "--output 
Warning: <FILE>" to save to a file.

Your server returns application/octet-stream as Content-Type. It can be problem as well

linev commented 5 years ago

I guess, you are using Python web server? Can you provide your script only without docker?

DraTeots commented 5 years ago

Yes, that is exactly the root of this issue, as I see it. I have some server witch works with Ranges, but jsroot doesn't use it. So what is the exact problem and what should be fixed.

Extracting example server setup is a bit hard, because this is actually jupyter/jupyterlab server part based on Tornado web server with a custom rules for root files:

class CorsStaticFileHandler(tornado.web.StaticFileHandler):
    def set_default_headers(self):
        self.set_header("Access-Control-Allow-Origin", "*")
        self.set_header("Access-Control-Allow-Headers", "x-requested-with")
        self.set_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')

def load_jupyter_server_extension(nb_app):
    web_app.add_handlers(host_pattern, [(r"/rjs/(.*)", CorsStaticFileHandler, {"path": server_root_dir, "default_filename": "README.md"})])

That is the reason I proposed the docker...

Lets go the other way. I'll try to add text/plain for root files

linev commented 5 years ago

That is the reason I proposed the docker...

I never tried docker on my computer, but we can try.

self.set_header("Access-Control-Allow-Origin", "*")

Such "Access-Control-Allow" headers does not required when HTML/JavaScript/ROOT files all placed on the same servers.

DraTeots commented 5 years ago

Hi! I just took a pause to double check everything on my side.

linev commented 5 years ago

Original error message appears when JSROOT analyzes HTTP response header. Total response length should not be significantly larger than requested size. Here is place where it checked: https://github.com/root-project/jsroot/blob/master/scripts/JSRootCore.js#L885-L893 One could make more debug output there. In principal, one can comment out this part and check if rest is working

linev commented 5 years ago

Any news here? Does this issue connected with #189 ? May be workaround there can help as well?

linev commented 5 years ago

I closing issue. If you still have the problem and workaround from #189 does not help - you are free to reopen issue again

DraTeots commented 5 years ago

Hi! Sorry, I've got trapped by a chain of conferences and shifted priorities because of it. I assumed that something "interplay between wrong SSL certificate, Chrome and your HTTP server" could be the problem in my case too. I haven't checked that yet with our setup. Will update this ticket if needed.

Thanks for the support!