Create a minimum REST Web Server with netcat nc

前端 未结 2 1743
半阙折子戏
半阙折子戏 2020-12-29 00:11

I was looking for the minimum REST web server using nc to be a one-liner for a Docker container. For instance:

* http://localhost/echo/marcello: prints marce         


        
2条回答
  •  滥情空心
    2020-12-29 00:51

    I hacked the example given by @syme at "https://stackoverflow.com/a/24342101/433814" and created the one-liner REST server. Some headers are missing, but it correctly handles HTTP GET and 404 of non-implemented resources.

    rm -f out ; mkfifo out ; trap "rm -f out" EXIT ; while true ; do cat out | nc -l 1500 > >(export REQUEST= ; while read line ; do line=$(echo "$line" | tr -d '[\r\n]') ; if echo "$line" | grep -qE '^GET /' ; then REQUEST=$(echo "$line" | cut -d ' ' -f2) ; elif [ "x$line" = x ] ; then HTTP_200="HTTP/1.1 200 OK" ; HTTP_LOCATION="Location:" ; HTTP_404="HTTP/1.1 404 Not Found" ; if echo $REQUEST | grep -qE '^/echo/' ; then printf "%s\n%s %s\n\n%s\n" "$HTTP_200" "$HTTP_LOCATION" $REQUEST ${REQUEST#"/echo/"} > out ; elif echo $REQUEST | grep -qE '^/date' ; then date > out ; elif echo $REQUEST | grep -qE '^/stats' ; then vmstat -S M > out ; elif echo $REQUEST | grep -qE '^/net' ; then ifconfig > out ; else printf "%s\n%s %s\n\n%s\n" "$HTTP_404" "$HTTP_LOCATION" $REQUEST "Resource $REQUEST NOT FOUND!" > out ; fi ; fi ; done) ; done
    

    The formatted version is located at https://gist.github.com/marcellodesales/9e4288f35ac2cc3e1b83#file-formatted

    The API above implements the following:

    • /echo/{name}

    Returns the given {name}

    $ curl -i http://localhost:1500/echo/marcello
    HTTP/1.1 200 OK
    Location: /echo/marcello
    
    marcello
    
    • /date

    Returns the server's date

    $ curl -i http://localhost:1500/date
    Sun Oct 19 14:12:27 PDT 2014
    
    • /stats

    Returns the server's stats

    $ curl -i http://localhost:1500/stats
    procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
     r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
     0  0     11    374    383   2198    0    0     6    22   33    8  2  2 97  0  0
    
    • /net

    Prints the server's network

    $ curl -i http://localhost:1500/net
    docker0   Link encap:Ethernet  HWaddr 56:84:7a:fe:97:99  
              inet addr:172.17.42.1  Bcast:0.0.0.0  Mask:255.255.0.0
              inet6 addr: fe80::5484:7aff:fefe:9799/64 Scope:Link
              UP BROADCAST MULTICAST  MTU:1500  Metric:1
              RX packets:120694 errors:0 dropped:0 overruns:0 frame:0
              TX packets:141757 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0 
              RX bytes:272911625 (272.9 MB)  TX bytes:289945068 (289.9 MB)
    
    eth0      Link encap:Ethernet  HWaddr 00:0c:29:1f:d3:b5  
              inet addr:192.168.248.206  Bcast:192.168.248.255  Mask:255.255.255.0
              inet6 addr: fe80::20c:29ff:fe1f:d3b5/64 Scope:Link
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:2322493 errors:0 dropped:0 overruns:0 frame:0
              TX packets:1098965 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000 
              RX bytes:2367412677 (2.3 GB)  TX bytes:700548644 (700.5 MB)
    
    lo        Link encap:Local Loopback  
              inet addr:127.0.0.1  Mask:255.0.0.0
              inet6 addr: ::1/128 Scope:Host
              UP LOOPBACK RUNNING  MTU:65536  Metric:1
              RX packets:151566 errors:0 dropped:0 overruns:0 frame:0
              TX packets:151566 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0 
              RX bytes:305833574 (305.8 MB)  TX bytes:305833574 (305.8 MB)
    
    • /ANYTHING/NOT/IMPLEMENTED

    For anything that the server does not implement, it prints the 404 message.

    $ curl -i http://localhost:1500/wrong
    HTTP/1.1 404 Not Found
    Location: /wrong
    
    Resource /wrong NOT FOUND!
    

    Here's the formatted solution from the GIST above. You can save it as "web.sh" and run :)

    rm -f out
    mkfifo out
    trap "rm -f out" EXIT
    while true
    do
      cat out | nc -l 1500 > >( # parse the netcat output, to build the answer redirected to the pipe "out".
        export REQUEST=
        while read line
        do
          line=$(echo "$line" | tr -d '[\r\n]')
    
          if echo "$line" | grep -qE '^GET /' # if line starts with "GET /"
          then
            REQUEST=$(echo "$line" | cut -d ' ' -f2) # extract the request
          elif [ "x$line" = x ] # empty line / end of request
          then
            HTTP_200="HTTP/1.1 200 OK"
            HTTP_LOCATION="Location:"
            HTTP_404="HTTP/1.1 404 Not Found"
            # call a script here
            # Note: REQUEST is exported, so the script can parse it (to answer 200/403/404 status code + content)
            if echo $REQUEST | grep -qE '^/echo/'
            then
                printf "%s\n%s %s\n\n%s\n" "$HTTP_200" "$HTTP_LOCATION" $REQUEST ${REQUEST#"/echo/"} > out
            elif echo $REQUEST | grep -qE '^/date'
            then
                date > out
            elif echo $REQUEST | grep -qE '^/stats'
            then
                vmstat -S M > out
            elif echo $REQUEST | grep -qE '^/net'
            then
                ifconfig > out
            else
                printf "%s\n%s %s\n\n%s\n" "$HTTP_404" "$HTTP_LOCATION" $REQUEST "Resource $REQUEST NOT FOUND!" > out
            fi
          fi
        done
      )
    done
    

提交回复
热议问题