|
| 1 | +# WebAssembly build |
| 2 | + |
| 3 | +The in-browser WebAssembly build of `git2cpp` is intended to behave as similar as possible to other |
| 4 | +builds but there are some differences when remotely accessing remote servers, in particular with |
| 5 | +blocking requests and the requirement for a CORS proxy server. |
| 6 | + |
| 7 | + |
| 8 | +## Blocking requests |
| 9 | + |
| 10 | +Remote `git2cpp` requests in non-WebAssembly builds are progressive and feedback is provided as the |
| 11 | +data is streamed back from the remote. But in WebAssembly builds such remote requests are blocking |
| 12 | +and no feedback can be provided until the entire response is received back from the remote. |
| 13 | +This can be a long time to wait without feedback, and if there is an error such that a response is |
| 14 | +not received it could block forever, leaving the in-browser terminal unusable. |
| 15 | + |
| 16 | +Hence the WebAssembly build limits http(s) requests with a timeout that defaults to 10 seconds. |
| 17 | +This timeout can be increased using the [`GIT_HTTP_TIMEOUT` environment variable](git_http_timeout). |
| 18 | + |
| 19 | +In addition, when a `git2cpp` response is received that is larger than 10 MB, a prompt is presented |
| 20 | +to the user to confirm whether to proceed to unpack the response or not. Note that the size of the |
| 21 | +response may be smaller or larger than the size of the directory structure it unpacks to. |
| 22 | + |
| 23 | + |
| 24 | +(cors_proxy)= |
| 25 | +## CORS proxy server |
| 26 | + |
| 27 | +The fetching of resources in a browser from one domain to another is often limited by a browser |
| 28 | +security feature called |
| 29 | +[Cross-Origin Resource Sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) |
| 30 | +(CORS). For this to be allowed the target domain must indicate it is happy to accept cross-origin |
| 31 | +requests by adding certain headers to `https` responses. Most git servers such as `github.com` do |
| 32 | +not add these headers, so a `git2cpp clone` from `github.com` will fail with a CORS error if run |
| 33 | +from within a browser whereas there is no such limitation if run from a terminal of a real computer. |
| 34 | + |
| 35 | +The solution to this problem is to use a separate CORS proxy server. The `git2cpp` remote request is |
| 36 | +sent to this intermediate server which send the request to the target server and as this request is |
| 37 | +coming from outside a browser it is not subject to CORS restrictions. The proxy receives the |
| 38 | +response from the target server and adds the required CORS headers before returning it to `git2cpp`. |
| 39 | + |
| 40 | +Various public CORS proxy servers are available for use or you serve your own. It can be useful to |
| 41 | +serve your own on `localhost` when experimenting to confirm that everything works as expected |
| 42 | +before moving on to a more complex solution. Be aware that the CORS proxy server is able to read the |
| 43 | +content of your request so be careful if you are using authentication tokens. |
| 44 | + |
| 45 | +The [`GIT_CORS_PROXY` environment variable](git_cors_proxy) is used to specify how the target URL is |
| 46 | +encoded in the CORS proxy URL. |
| 47 | + |
| 48 | +### Example running a local CORS proxy server |
| 49 | + |
| 50 | +If you are running a local [cockle](https://github.com/jupyterlite/cockle) or |
| 51 | +[JupyterLite terminal](https://github.com/jupyterlite/terminal) deployment you can also run a local |
| 52 | +CORS proxy such as [CORS Anywhere](https://github.com/Rob--W/cors-anywhere) to test it out. |
| 53 | +In a separate terminal on your host machine on which you have `nodejs` available, `cd` to a new |
| 54 | +clean directory, and download and run the CORS proxy server using: |
| 55 | + |
| 56 | +```js |
| 57 | +npm install cors-anywhere |
| 58 | +HOST=localhost PORT=8881 node node_modules/cors-anywhere/server.js |
| 59 | +``` |
| 60 | + |
| 61 | +This will start the CORS proxy server listening on `http://localhost:8881/`. To use this in your |
| 62 | +local `cockle` or `JupyterLite terminal` deployment in your browser set the `CORS_PROXY_URL` to be |
| 63 | +```bash |
| 64 | +export GIT_CORS_PROXY=http://localhost:8881/ |
| 65 | +``` |
| 66 | +and then try a `git2cpp clone` using something like: |
| 67 | +```bash |
| 68 | +git2cpp clone https://github.com/some-organisation/some-repository |
| 69 | +``` |
| 70 | + |
| 71 | +### Example using a public CORS proxy server |
| 72 | + |
| 73 | +There is a public instance of [CORS Anywhere](https://github.com/Rob--W/cors-anywhere) available at |
| 74 | +`https://cors-anywhere.herokuapp.com/`. This can be used for demonstration purposes but it requires |
| 75 | +an explicit opt-in and your access will be time-limited. To request temporary access go to |
| 76 | +`https://cors-anywhere.herokuapp.com/` and follow the instructions there. |
| 77 | + |
| 78 | +Once you have access, you can try this out in one of the public deployments such as those at |
| 79 | +[https://jupyterlite.github.io/cockle](https://jupyterlite.github.io/cockle) or |
| 80 | +[https://jupyterlite.github.io/terminal](https://jupyterlite.github.io/terminal). |
| 81 | + |
| 82 | +Set the `CORS_PROXY_URL` to be |
| 83 | +```bash |
| 84 | +export GIT_CORS_PROXY=https://cors-anywhere.herokuapp.com/ |
| 85 | +``` |
| 86 | +and then try a `git2cpp clone` using something like: |
| 87 | +```bash |
| 88 | +git2cpp clone https://github.com/some-organisation/some-repository |
| 89 | +``` |
0 commit comments