copy / v86

x86 PC emulator and x86-to-wasm JIT, running in the browser
https://copy.sh/v86/
BSD 2-Clause "Simplified" License
19.9k stars 1.41k forks source link

HTTP/1.1 502 error [fetch-based network] #1186

Closed coderofsalvation closed 1 day ago

coderofsalvation commented 3 days ago

I've got a buildroot going (https://forgejo.isvery.ninja/xrsh/xrsh-buildroot/src/branch/main/dist) and have enabled fetchbased network-config in the browser:

{
   ...
    network_relay_url: "fetch", // or websocket proxy "wss://relay.widgetry.org/",
    cmdline: "rw root=host9p rootfstype=9p rootflags=trans=virtio,cache=loose modules=virtio_pci tsc=reliable init_on_freg|=on vga=ask",
    net_device:{
      relay_url:"fetch",
      type:"virtio"
    },
  ...
}

which leads to an 'almost' succesful networkable session, with the latest ptr-release which includes https://github.com/copy/v86/pull/1182:

$ ifconfig                                                                      
eth0      Link encap:Ethernet  HWaddr 00:22:15:3D:8A:B7                         
          inet addr:192.168.86.100  Bcast:192.168.86.255  Mask:255.255.255.0    
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1                    
          RX packets:6 errors:0 dropped:0 overruns:0 frame:1                    
          TX packets:4 errors:0 dropped:0 overruns:0 carrier:0                  
          collisions:0 txqueuelen:1000                                          
          RX bytes:844 (844.0 B)  TX bytes:803 (803.0 B)                        

lo        Link encap:Local Loopback                                             
          inet addr:127.0.0.1  Mask:255.0.0.0                                   
          UP LOOPBACK RUNNING  MTU:65536  Metric:1                              
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0                    
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0                  
          collisions:0 txqueuelen:1000                                          
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)                                

$ wget https://xrsh.isvery.ninja/index.html                                     
Connecting to xrsh.isvery.ninja (192.168.87.1:443)                              
wget: can't connect to remote host (192.168.87.1): Connection refused           

$ wget http://2wa.isvery.ninja                                                  
Connecting to 2wa.isvery.ninja (192.168.87.1:80)                                
wget: server returned error: HTTP/1.1 502 Fetch Error                           

$ cat /var/log/network.log                                                      
udhcpc: started, v1.33.0                                                        
udhcpc: sending discover                                                        
udhcpc: sending select for 192.168.86.100                                       
udhcpc: lease of 192.168.86.100 obtained, lease time 134217728                  
deleting routers                                                                
adding dns 192.168.86.1  

I've even enabled wget-with-SSL-via-TLS option in busybox but can't seem to do a HTTP request.

SuperMaxusa commented 3 days ago

Only HTTP is available in fetch-based networking, but your browser could make a request over HTTPS in some cases (https://github.com/copy/v86/commit/daa80bb608606e647f05574c507583a5ce89cfa4).

About HTTP/1.1 502 Fetch Error, can you try run wget -S -O - http://2wa.isvery.ninja and look at the browser console? If this is a CORS-related error, see #1180.

coderofsalvation commented 3 days ago

Thank you for looking into it. After you mentioning CORS, I was having more stabs at it...and guess what:

Maybe the fetch-based network needs to always translate localhost to 127.0.0.1?

BTW Thanks for the HTTPS-note: I was able to wget a https URL (by running v86 from https, and leaving out the protocol: wget 2wa.isvery.ninja)

copy commented 2 days ago

I don't see how localhost vs 127.0.0.1 can make a difference here (except in the Origin header sent by the browser in the fetch request).

Could you please provide the following information?

coderofsalvation commented 2 days ago

Oh that did/outputted nothing, I even tried without the '-'

image

chschnell commented 2 days ago

Note that you can drop network_relay_url entirely from your V86 configuration, it's deprecated and has been replaced by net_device.relay_url (which you already use a few lines down).

Here's an URL that should work without a proxy (I use it for my own tests):

wget -O - http://www.rekoba.de/~cs/

The page is unimportant, but this URL is served via HTTPS, the server's certificate is legit, and this URL is CORS-enabled.

SuperMaxusa commented 2 days ago

For me, on Firefox it fails with error CORS header 'Access-Control-Allow-Origin' missing (tested on local server with your buildroot and https://copy.sh/v86/?profile=archlinux&relay_url=fetch&c=/root/networking.sh):

/ # wget -S -O - http://2wa.isvery.ninja
Connecting to 2wa.isvery.ninja (192.168.87.1:80)
  HTTP/1.1 502 Fetch Error
wget: server returned error: HTTP/1.1 502 Fetch Error

In DevTools, Firefox send a OPTIONS request like this:

OPTIONS / HTTP/1.1
Host: 2wa.isvery.ninja
User-Agent: Mozilla/5.0 <...> Firefox/132.0
Accept: */*
<...>
Access-Control-Request-Method: GET
Access-Control-Request-Headers: user-agent
Referer: http://localhost/
Origin: http://localhost

Your server responded with this:

HTTP/1.1 200 OK
permissions-policy: interest-cohort=()
vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers
date: Wed, 27 Nov 2024 17:25:05 GMT
content-length: 0
gitlab-lb: haproxy-pages-04-lb-gprd
gitlab-sv: pages-us-east1-c

For understanding, the browser firstly sends a Preflight request to get CORS rules from the server, and then other requests after checking. If there is no any CORS-related headers in the response, your browser assumes that CORS is blocked. That is the reason why Firefox cannot send a GET request.


On Chrome, it works properly:

/ # wget -S -O - http://2wa.isvery.ninja
Connecting to 2wa.isvery.ninja (192.168.87.1:80)
  HTTP/1.1 200 
  x-was-fetch-redirected: true
  x-fetch-resp-url: https://2wa.isvery.ninja/
  Connection: closed
  <...>

writing to stdout
<!DOCTYPE html>
<html>
        <head>
                <meta http-equiv="X-UA-Compatible" content="IE=Edge"/> 
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
                <title>2WA website</title>

Chrome only sends a GET request without an OPTIONS request, which looks strange.

Unfortunately, I can't get raw request by Chrome, only some headers from the GET request:

:authority: 2wa.isvery.ninja
:method: GET
:path: /
:scheme: https
accept: */*
cache-control: no-cache
origin: http://localhost
pragma: no-cache
priority: u=1, i
referer: https://copy.sh/
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 <...> Chrome/131.0.0.0 Safari/537.36
copy commented 1 day ago

@SuperMaxusa Thanks for the research!

Let's close this as it's a problem with the configuration of the server, and not a bug in v86.