Skip to content

Commit

Permalink
Update jsroot and httpserver docs
Browse files Browse the repository at this point in the history
  • Loading branch information
linev committed Sep 23, 2024
1 parent 2f3cddf commit 9b5309f
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 47 deletions.
70 changes: 55 additions & 15 deletions documentation/HttpServer/HttpServer.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,29 @@ THttpServer does not take ownership over registered objects - they should be del
If the objects content is changing in the application, one could enable monitoring flag in the browser - then objects view will be regularly updated.


## Accessing file system

THttpServer provides partial access to the files from file system.
First of all, JSROOT scripts and files can be accessed via "jsrootsys/" path like "http://localhost:8080/jsrootsys/modules/core.mjs".
Files from ROOT install directory can be get via "rootsys/" path like "http://localhost:8080/rootsys/icons/about.xpm".
Also files from current directory where ROOT is running can be accessed via "currentdir/" path like "http://localhost:8080/currentdir/file.txt".

If necessary, one can add custom path as well, using [THttpServer::AddLocation](https://root.cern/doc/master/classTHttpServer.html#a5322c3bbfddb8eb6849297d83ccaf87f) method:

```cpp
serv->AddLocation("mydir/", "/home/user/specials");
```
Then files from that directory could be addressed via URL like "http://localhost:8080/mydir/myfile.root"
## Command interface
THttpServer class provide simple interface to invoke command from web browser.
One just register command like:
```cpp
serv->RegisterCommand("/DoSomething","SomeFunction()");
serv->RegisterCommand("/DoSomething", "SomeFunction()");
```

Element with name `DoSomething` will appear in the web browser and can be clicked.
Expand All @@ -105,20 +121,20 @@ One could configure argument(s) for the command.
For that one should use `%arg1`, `%arg2` and so on identifiers. Like:

```cpp
serv->RegisterCommand("/DoSomething","SomeFunction(%arg1%,%arg2%)");
serv->RegisterCommand("/DoSomething", "SomeFunction(%arg1%,%arg2%)");
```
User will be requested to enter arguments values, when command element clicked in the browser.
Example of the command which executes arbitrary string in application via ProcessLine looks like:
```cpp
serv->RegisterCommand("/Process","%arg1%");
serv->RegisterCommand("/Process", "%arg1%");
```

When registering command, one could specify icon name which will be displayed with the command.

```cpp
serv->RegisterCommand("/DoSomething","SomeFunction()", "rootsys/icons/ed_execute.png");
serv->RegisterCommand("/DoSomething", "SomeFunction()", "rootsys/icons/ed_execute.png");
```
In example usage of images from `$ROOTSYS/icons` directory is shown. One could prepend `button;`
Expand Down Expand Up @@ -200,14 +216,14 @@ Hidden folders or objects can not be accessed via http protocol.
By default server runs in readonly mode and do not allow methods execution via 'exe.json' or 'exe.bin' requests. To allow such action, one could either grant generic access for all or one could allow to execute only special method:

```cpp
serv->Restrict("/Folder/histo1", "allow=all");
serv->Restrict("/Folder/histo1", "allow_method=GetTitle");
serv->Restrict("/Folder/histo1", "allow=all");
serv->Restrict("/Folder/histo1", "allow_method=GetTitle");
```
One could provide several options for the same item, separating them with '&' sign:
```cpp
serv->Restrict("/Folder/histo1", "allow_method=GetTitle&hide=guest");
serv->Restrict("/Folder/histo1", "allow_method=GetTitle&hide=guest");
```

Complete list of supported options could be found in [TRootSniffer:Restrict()](https://root.cern/doc/master/classTRootSniffer.html#a8af1f11cbfb9c895f968ec0594794120) method documentation.
Expand Down Expand Up @@ -366,6 +382,7 @@ The following requests can be performed:
| :----------- | :---------------- |
| `root.bin` | binary data produced by object streaming with `TBufferFile` |
| `root.json` | ROOT JSON representation for object and objects members |
| `file.root` | Creates TMemFile with the only object, from ROOT 6.32 |
| `root.xml` | ROOT XML representation |
| `root.png` | PNG image (if object drawing implemented) |
| `root.gif` | GIF image |
Expand All @@ -386,7 +403,7 @@ All data will be automatically zipped if '.gz' extension is appended. Like:
If the access to the server is restricted with htdigest, it is recommended to use the **curl** program since only curl correctly implements such authentication method. The command will look like:

```bash
[shell] curl --user "account:password" http://localhost:8080/Objects/subfolder/obj/root.json --digest -o root.json
[shell] curl --user "accout:password" http://localhost:8080/Objects/subfolder/obj/root.json --digest -o root.json
```


Expand Down Expand Up @@ -483,16 +500,18 @@ One also used `exe.bin` method - in this case results of method execution will b
[shell] wget 'http://localhost:8080/Objects/subfolder/obj/exe.json?method=Clone&_destroy_result_' -O clone.json
```

If method required object as argument, it could be posted in binary or XML format as POST request. If binary form is used, one should specify following parameters:
If method required object as argument, it could be posted in binary, JSON or XML format as POST request.
If binary form is used, one should specify following parameters:

```bash
[shell] wget 'http://localhost:8080/hist/exe.json?method=Add&h1=_post_object_&_post_class_=TH1I&c1=10' --post-file=h.bin -O res.json
```

Here is important to specify post object class, which is not stored in the binary buffer. When used XML form (produced with [TBufferXML::ConvertToXML](https://root.cern/doc/master/classTBufferXML.html#a31320042dda441167ecb1b6f13092e89)) method, only string with XML code could be specified:
Here is important to specify post object class, which is not stored in the binary buffer.
When submitting argument as JSON produced with [TBufferJSON::ToJSON](https://root.cern/doc/master/classTBufferJSON.html#a49f3c7b200113d7009d61d75c933c398) method, class is not required:

```bash
[shell] wget 'http://localhost:8080/hist/exe.json?method=Add&h1=_post_object_xml_&c1=10' --post-file=h.xml -O res.json
[shell] wget 'http://localhost:8080/hist/exe.json?method=Add&h1=_post_object_json_&c1=10' --post-file=h.json -O res.json
```

To get debug information about command execution, one could submit `exe.txt` request with same arguments.
Expand Down Expand Up @@ -563,14 +582,35 @@ import { httpRequest, draw } from './jsrootsys/modules/core.mjs';
let res = await httpRequest("your_server/multi.json?number=3", "multi",
"Files/job1.root/hpx/root.json\nFiles/job1.root/hpxpy/root.json\nFiles/job1.root/hprof/root.json\n");
for (let n = 0; n < res.length; ++n) {
console.log('Requested element ', res[n]._typename);
console.log('Requested element of type', res[n]._typename);
// draw('drawid', res[n], 'hist');
}
```

Here argument "multi" identifies, that server response should be parsed with `parseMulti()` function, which correctly interprets JSON code, produced by `multi.json` request. When sending such request to the server, one should provide list of objects names and not forget "?number=N" parameter in the request URL string.


## Using unix sockets

Starting from ROOT version 6.28, one can start server with unix socket. Just do:

Just call:
```cpp
[root] new THttpServer("socket:/tmp/root.socket")
```
Name of socket should be unique and not match any existing files.

Most easy way to access `THttpServer` running via unix socket is to configure ssh tunnel:
```
[shell] ssh -L 7654:/tmp/root.socket localhost
```

Once such tunnel is configured one can open following URL in web browser:
```
[shell] xdg-open http://localhost:7654
```


## Websockets supports

Websockets support available starting from ROOT v6.12.
Expand All @@ -586,7 +626,7 @@ public:
TUserHandler(const char *name, const char *title) : THttpWSHandler(name, title) {}

// provide custom HTML page when open correspondent address
TString GetDefaultPageContent() override { return ""; }
TString GetDefaultPageContent() override { return "file:ws.htm"; }

Bool_t ProcessWS(THttpCallArg *arg) override;
};
Expand Down Expand Up @@ -637,5 +677,5 @@ serv->Register(handler);
```
After that web socket connection can be established with the address `ws://host_name:8080/name1/root.websocket`
Example client code can be found in `$ROOTSYS/tutorials/http/ws.htm` file. Actually, custom HTML page for
websocket handler can be specified with `TUserHandler::GetDefaultPageContent()` method returning `"file:ws.htm"`.
Example client code can be found in `$ROOTSYS/tutorials/http/ws.htm` file. Custom HTML page for
websocket handler is specified with `TUserHandler::GetDefaultPageContent()` method returning `"file:ws.htm"`.
Loading

0 comments on commit 9b5309f

Please sign in to comment.