Archive for the ‘ Miscellaneous ’ Category

Get HTTP headers

Linux – view HTTP header response using curl, httpie, GET, nmap


Most users are interested in the content they receive when they visit a web site. There is an extra information web clients and servers exchange – HTTP headers. HTTP headers let the client and the server pass additional information with an HTTP request or response.

So how do we view the HTTP response from a remove web server? There are several tools for these

1. Curl : use ‘-I’ flag

   -I, --head
          (HTTP FTP FILE) Fetch the headers only! HTTP-servers feature the command HEAD which this uses to get nothing but  the  header  of  a
          document. When used on an FTP or FILE file, curl displays the file size and last modification time only.
$ curl -I google.com
HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Sun, 02 Aug 2020 13:48:01 GMT
Expires: Tue, 01 Sep 2020 13:48:01 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 219
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN

2. httpie : Use ‘-h h’ flag

--print WHAT, -p WHAT
       String specifying what the output should contain:
      'H' request headers
      'B' request body
      'h' response headers
      'b' response body
$ http www.google.com --print h
 HTTP/1.1 200 OK
 Cache-Control: private, max-age=0
 Content-Encoding: gzip
 Content-Length: 5256
 Content-Type: text/html; charset=ISO-8859-1
 Date: Sun, 02 Aug 2020 13:50:50 GMT
 Expires: -1
 P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
 Server: gws
 Set-Cookie: 1P_JAR=2020-08-02-13; expires=Tue, 01-Sep-2020 13:50:50 GMT; path=/; domain=.google.com; Secure
 Set-Cookie: NID=TRUNCATED; expires=Mon, 01-Feb-2021 13:50:50 GMT; path=/; domain=.google.com; HttpOnly
 X-Frame-Options: SAMEORIGIN
 X-XSS-Protection: 0

3. GET – lwp-request : ‘Ed’ flag

In many Linux distros, GET is an alias for lwp-request. It gives way more detailed information in the response header, including SSL parameters.

  -E  Print response status chain with full response headers.

  -d  Do not print the content of the response.
$ GET linux.com -Ed
GET http://linux.com
User-Agent: lwp-request/6.31 libwww-perl/6.31

301 Moved Permanently
Cache-Control: public, max-age=86400
Connection: close
Date: Sun, 02 Aug 2020 13:56:35 GMT
Via: 1.1 varnish
Accept-Ranges: bytes
Age: 43368
Location: https://linux.com/
Server: nginx
Vary: Cookie, Cookie
Content-Length: 162
Content-Type: text/html
Client-Date: Sun, 02 Aug 2020 13:56:35 GMT
Client-Peer: REDACTED
Client-Response-Num: 1
Title: 301 Moved Permanently
X-Cache: HIT, HIT
X-Cache-Hits: 1, 1
X-Pantheon-Styx-Hostname: styx-fe3-a-745747b57-x7rhq
X-Served-By: cache-mdw17324-MDW, cache-fty21379-FTY
X-Styx-Req-Id: 01697a62-d463-11ea-a64f-aabcb0e0cfdc
X-Timer: S1596376596.936127,VS0,VE1

GET https://linux.com/
User-Agent: lwp-request/6.31 libwww-perl/6.31

301 Moved Permanently
Cache-Control: public, max-age=86400
Connection: close
Date: Sun, 02 Aug 2020 13:56:36 GMT
Via: 1.1 varnish
Accept-Ranges: bytes
Age: 43368
Location: https://www.linux.com/
Server: nginx
Vary: Cookie, Cookie
Content-Length: 0
Content-Type: text/html; charset=UTF-8
Client-Date: Sun, 02 Aug 2020 13:56:36 GMT
Client-Peer: REDACTED
Client-Response-Num: 1
Client-SSL-Cert-Issuer: /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
Client-SSL-Cert-Subject: /CN=linux.com
Client-SSL-Cipher: ECDHE-RSA-AES128-GCM-SHA256
Client-SSL-Socket-Class: IO::Socket::SSL
Strict-Transport-Security: max-age=300
X-Cache: HIT, HIT
X-Cache-Hits: 1, 1
X-Pantheon-Styx-Hostname: styx-fe3-b-64d9844f89-tc7zl
X-Served-By: cache-mdw17340-MDW, cache-pdk17820-PDK
X-Styx-Req-Id: 01bf3709-d463-11ea-baef-1ede833e594e
X-Timer: S1596376596.065153,VS0,VE1

GET https://www.linux.com/
User-Agent: lwp-request/6.31 libwww-perl/6.31

200 OK
Cache-Control: public, max-age=1800
Connection: close
Date: Sun, 02 Aug 2020 13:56:36 GMT
Via: 1.1 varnish
Accept-Ranges: bytes
Age: 1659
Server: nginx
Vary: Accept-Encoding, Cookie, Cookie
Content-Length: 126289
Content-Type: text/html; charset=UTF-8
Client-Date: Sun, 02 Aug 2020 13:56:36 GMT
Client-Peer: REDACTED
Client-Response-Num: 1
Client-SSL-Cert-Issuer: /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
Client-SSL-Cert-Subject: /CN=linux.com
Client-SSL-Cipher: ECDHE-RSA-AES128-GCM-SHA256
Client-SSL-Socket-Class: IO::Socket::SSL
Link: <https://www.linux.com/wp-json/>; rel="https://api.w.org/"
Link: <https://www.linux.com/>; rel=shortlink
Strict-Transport-Security: max-age=300
Title: Linux.com - News For Open Source Professionals
X-Cache: HIT, MISS
X-Cache-Hits: 5, 0
X-Meta-Charset: UTF-8
X-Meta-Description: Linux.com is the go-to resource for open source professionals to learn about the latest in Linux and open source technology, careers, best practices, and industry trends. Get news, information, and tutorials to help advance your next project or career – or just to simply stay informed.
X-Meta-Generator: WordPress 5.4.2
X-Meta-Twitter-Card: summary_large_image
X-Meta-Twitter-Description: Linux.com is the go-to resource for open source professionals to learn about the latest in Linux and open source technology, careers, best practices, and industry trends. Get news, information, and tutorials to help advance your next project or career – or just to simply stay informed.
X-Meta-Twitter-Image: https://www.linux.com/wp-content/uploads/2019/08/ldc_social.jpg
X-Meta-Twitter-Title: Linux.com - News For Open Source Professionals
X-Meta-Viewport: width=device-width, initial-scale=1.0
X-Pantheon-Styx-Hostname: styx-fe3-a-745747b57-mfmk7
X-Served-By: cache-mdw17340-MDW, cache-pdk17866-PDK
X-Styx-Req-Id: 1df2da1b-d4c4-11ea-84e9-925461917092
X-Timer: S1596376596.261327,VS0,VE18

Nmap : –script=http-headers flag

Nmap is a network discovery tool but it can be used for scanning http headers as well. The port number has to be specified, otherwise nmap will scan several common ports.

$ nmap --script=http-headers google.com -p 80

Starting Nmap 7.60 ( https://nmap.org ) at 2020-08-02 10:00 PDT
Nmap scan report for google.com (172.217.15.110)
Host is up (0.026s latency).
rDNS record for 172.217.15.110: iad30s21-in-f14.1e100.net

PORT   STATE SERVICE
80/tcp open  http
| http-headers: 
|   Location: http://www.google.com/
|   Content-Type: text/html; charset=UTF-8
|   Date: Sun, 02 Aug 2020 14:00:10 GMT
|   Expires: Tue, 01 Sep 2020 14:00:10 GMT
|   Cache-Control: public, max-age=2592000
|   Server: gws
|   Content-Length: 219
|   X-XSS-Protection: 0
|   X-Frame-Options: SAMEORIGIN
|   Connection: close
|   
|_  (Request type: GET)

Nmap done: 1 IP address (1 host up) scanned in 0.69 seconds



$ nmap --script=http-headers google.com -p 443

Starting Nmap 7.60 ( https://nmap.org ) at 2020-08-02 10:00 PDT
Nmap scan report for google.com (172.217.15.110)
Host is up (0.027s latency).
rDNS record for 172.217.15.110: iad30s21-in-f14.1e100.net

PORT    STATE SERVICE
443/tcp open  https
| http-headers: 
|   Location: https://www.google.com/
|   Content-Type: text/html; charset=UTF-8
|   Date: Sun, 02 Aug 2020 14:00:13 GMT
|   Expires: Tue, 01 Sep 2020 14:00:13 GMT
|   Cache-Control: public, max-age=2592000
|   Server: gws
|   Content-Length: 220
|   X-XSS-Protection: 0
|   X-Frame-Options: SAMEORIGIN
|   Alt-Svc: h3-29=":443"; ma=2592000,h3-27=":443"; ma=2592000,h3-T050=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
|   Connection: close
|   
|_  (Request type: GET)

Nmap done: 1 IP address (1 host up) scanned in 0.74 seconds


Creating a text file in Linux


In Unix, everything is a file. In this particular case though we will be demonstrating how to create a text file. Of course, these are some of the many ways of creating a file

touch

Just touch it! – touch command followed by some file name and a file will magically appear.

$ ls linuxfreelancer
ls: cannot access 'linuxfreelancer': No such file or directory

$ touch linuxfreelancer

$ $ ls -l linuxfreelancer 
-rw-rw-r-- 1 daniel daniel 0 Feb  8 16:53 linuxfreelancer

vi

vi or any text editor. In fact, any process which writes to a file.

$ vi linuxfreelancer

Save with “:wq” in vi to save the file.

cat

Write multi-line text with “Here Document” syntax in bash.

$ cat <<EOF>linuxfreelancer
my blog is at https://www.linuxfreelancer.com
EOF

$ cat linuxfreelancer 
my blog is at https://www.linuxfreelancer.com
$

echo

The echo command with some redirection –

$ echo 'My blog is at https://linuxfreelancer.com' > linuxfreelancer

$ cat linuxfreelancer 
My blog is at https://linuxfreelancer.com

Redirection

You can redirect the output of any command to a new file

$ ps > ps.output
$ cat ps.output 
  PID TTY          TIME CMD
 2703 pts/0    00:00:00 bash
 3290 pts/0    00:00:00 ps

tee

$ tee linuxfreelancer
Writing for my blog linuxfreelancer.com
Writing for my blog linuxfreelancer.com
...Crl+X

$ cat linuxfreelancer 
Writing for my blog linuxfreelancer.com

$ 

Why does the tee command repeat what I typed? that is what it does – it reads from standard input and write to standard output and file at the same time.

Exclude files from Dockerfile

How to exclude files from being added to docker image

TL;DR – use .dockerignore file, Docker’s equivalent of .gitignore for git


When building docker images, minimizing the size of the image is the goal. During building docker images with Dockerfile, especially with in a git repository, we might unintentionally add all the files into the docker image.

It is not uncommon to have something like “ADD . /app” in your Dockerfile. There are two ways to prevent this

  • Explicitly add only the files you need to Dockfile
  • Use .dockerignore file

A typical .dockerignore files in a git repo directory might look like this –

daniel@hidmo:/tmp/myapp$ ls -al
total 56
drwxr-xr-x  4 daniel daniel 4096 Dec 17 17:51 .
drwxrwxrwt 20 root   root   4096 Dec 17 17:51 ..
-rwxr-xr-x  1 daniel daniel  338 Dec 17 17:41 build-image.sh
drwxr-xr-x  2 daniel daniel 4096 Dec 17 17:41 .cache
-rw-r--r--  1 daniel daniel  245 Dec 17 17:41 Dockerfile
-rw-r--r--  1 daniel daniel  102 Dec 17 17:51 .dockerignore
drwxr-xr-x  8 daniel daniel 4096 Dec 17 17:52 .git
-rw-r--r--  1 daniel daniel    6 Dec 17 17:51 .gitignore
-rw-r--r--  1 daniel daniel  133 Dec 17 17:41 README
-rw-r--r--  1 daniel daniel  181 Dec 17 17:41 requirements.txt
-rw-r--r--  1 daniel daniel 7871 Dec 17 17:41 web.py
-rw-r--r--  1 daniel daniel 7871 Dec 17 17:50 web.pyc
daniel@hidmo:/tmp/myapp$ cat .dockerignore 
# Exclude files from being added to docker image
.git
.gitignore
.cache
.pyc
Dockerfile
README
readme

References

https://docs.docker.com/engine/reference/builder/#dockerignore-file

Linux – Cheat sheet

Using curl to get help on Linux commands, programming languages and more. The most comprehensive cheat sheet.

If you are looking for a Linux and programming cheat sheet, please check
https://github.com/chubin/cheat.sh

It provides nicely colored help page, with plenty of examples in a CLI. Here are some sample runs I did.

Curl cheat sheet


daniel@hidmo:/tmp$ curl cheat.sh/curl
# Download a single file
curl http://path.to.the/file

# Download a file and specify a new filename
curl http://example.com/file.zip -o new_file.zip

# Download multiple files
curl -O URLOfFirstFile -O URLOfSecondFile

# Download all sequentially numbered files (1-24)
curl http://example.com/pic[1-24].jpg

# Download a file and follow redirects
curl -L http://example.com/file

# Download a file and pass HTTP Authentication
curl -u username:password URL 

# Download a file with a Proxy
curl -x proxysever.server.com:PORT http://addressiwantto.access

# Download a file from FTP
curl -u username:password -O ftp://example.com/pub/file.zip

# Get an FTP directory listing
curl ftp://username:password@example.com

# Resume a previously failed download
curl -C - -o partial_file.zip http://example.com/file.zip

# Fetch only the HTTP headers from a response
curl -I http://example.com

# Fetch your external IP and network info as JSON
curl http://ifconfig.me/all/json

# Limit the rate of a download
curl --limit-rate 1000B -O http://path.to.the/file

# POST to a form
curl -F &quot;name=user&quot; -F &quot;password=test&quot; http://example.com

# POST JSON Data
curl -H &quot;Content-Type: application/json&quot; -X POST -d '{&quot;user&quot;:&quot;bob&quot;,&quot;pass&quot;:&quot;123&quot;}' http://example.com

# POST data from the standard in / share data on sprunge.us
curl -F 'sprunge=&amp;lt;-' sprunge.us

Python lists cheat list

daniel@hidmo:/tmp$ curl cheat.sh/python/list
#  python - Why does += behave unexpectedly on lists?
#  
#  The general answer is that += tries to call the __iadd__ special
#  method, and if that isn't available it tries to use __add__ instead.
#  So the issue is with the difference between these special methods.
#  
#  The __iadd__ special method is for an in-place addition, that is it
#  mutates the object that it acts on. The __add__ special method returns
#  a new object and is also used for the standard + operator.
#  
#  So when the += operator is used on an object which has an __iadd__
#  defined the object is modified in place. Otherwise it will instead try
#  to use the plain __add__ and return a new object.
#  
#  That is why for mutable types like lists += changes the object's
#  value, whereas for immutable types like tuples, strings and integers a
#  new object is returned instead (a += b becomes equivalent to a = a +
#  b).
#  
#  For types that support both __iadd__ and __add__ you therefore have to
#  be careful which one you use. a += b will call __iadd__ and mutate a,
#  whereas a = a + b will create a new object and assign it to a. They
#  are not the same operation!

>>> a1 = a2 = [1, 2]
>>> b1 = b2 = [1, 2]
>>> a1 += [3]          # Uses __iadd__, modifies a1 in-place
>>> b1 = b1 + [3]      # Uses __add__, creates new list, assigns it to b1
>>> a2
[1, 2, 3]              # a1 and a2 are still the same list
>>> b2
[1, 2]                 # whereas only b1 was changed

#  For immutable types (where you don't have an __iadd__) a += b and a =
#  a + b are equivalent. This is what lets you use += on immutable types,
#  which might seem a strange design decision until you consider that
#  otherwise you couldn't use += on immutable types like numbers!
#  
#  [Scott Griffiths] [so/q/2347265] [cc by-sa 3.0]

Golang concurrency cheat sheet

daniel@hidmo:/tmp$ curl cheat.sh/go/concurrency
/*
 * go - When should I use concurrency in golang?
 * 
 * Not an expert in Go (yet) but I'd say:
 * 
 * Whenever it is easiest to do so.
 * 
 * The beauty of the concurrency model in Go is that it is not
 * fundamentally a multi-core architecture with checks and balances where
 * things usually break - it is a multi-threaded paradigm that not only
 * fits well into a multi-core architecture, it also fits well into a
 * distributed system architecture.
 * 
 * You do not have to make special arrangements for multiple goroutines
 * to work together harmoniously - they just do!
 * 
 * Here's an example of a naturally concurrent algorithm - I want to
 * merge multiple channels into one. Once all of the input channels are
 * exhausted I want to close the output channel.
 * 
 * It is just simpler to use concurrency - in fact it doesn't even look
 * like concurrency - it looks almost procedural.
 */

/*
  Multiplex a number of channels into one.
*/
func Mux(channels []chan big.Int) chan big.Int {
    // Count down as each channel closes. When hits zero - close ch.
    var wg sync.WaitGroup
    wg.Add(len(channels))
    // The channel to output to.
    ch := make(chan big.Int, len(channels))

    // Make one go per channel.
    for _, c := range channels {
        go func(c &amp;lt;-chan big.Int) {
            // Pump it.
            for x := range c {
                ch &amp;lt;- x
            }
            // It closed.
            wg.Done()
        }(c)
    }
    // Close the channel when the pumping is finished.
    go func() {
        // Wait for everyone to be done.
        wg.Wait()
        // Close.
        close(ch)
    }()
    return ch
}

/*
 * The only concession I have to make to concurrency here is to use a
 * sync.WaitGroup as a counter for concurrent counting.
 * 
 * Note that this is not purely my own work - I had a great deal of help
 * with this here (https:stackoverflow.com/q/19192377/823393).
 * 
 * [OldCurmudgeon] [so/q/19747950] [cc by-sa 3.0]
 */

Please check
https://github.com/chubin/cheat.sh for more information on installation and using its comprehensive features.

curl – use variables to show response times and other parameters


curl is a tool to interact with a server for transferring data. Although it supports various protocols, it is most commonly used with HTTP/S. It is sort of a browser for CLI folks and a go to tool when writing scripts to interact with servers.


In addition to transferring data, how do we show request and response parameters with curl. The answer is using variables, the complete list of variables can be found here.

Example – use “time_total” to show the total time, in seconds, that the full operation lasted.

$ curl  -w %{time_total} https://www.gcplinux.com
1.149143

It is best to add the variables in a file and use curl to reference the file for better formatting. Here I have added several http request and response variables I am interested in, such as num_connects, size_download, size_header, time_namelookup, time_pretransfer etc.


daniel@hidmo:/tmp$ cat ccurl.txt 
      url_effective:  %{url_effective}\n
       content_type:  %{content_type}\n
          http_code:  %{http_code}\n
       http_version:  %{http_version}\n
       num_connects:  %{num_connects}\n
      num_redirects:  %{num_redirects}\n
          remote_ip:  %{remote_ip}\n
      size_download:  %{size_download}\n
        size_header:  %{size_header}\n
    time_namelookup:  %{time_namelookup}\n
       time_connect:  %{time_connect}\n
    time_appconnect:  %{time_appconnect}\n
   time_pretransfer:  %{time_pretransfer}\n
      time_redirect:  %{time_redirect}\n
 time_starttransfer:  %{time_starttransfer}\n
                    ----------\n
         time_total:  %{time_total}\n


daniel@hidmo:/tmp$ curl -H 'Cache-Control: no-cache' -L -w "@ccurl.txt" -o /dev/null -s https://www.gcplinux.com
      url_effective:  https://gcplinux.com/
       content_type:  text/html; charset=UTF-8
          http_code:  200
       http_version:  1.1
       num_connects:  2
      num_redirects:  1
          remote_ip:  162.247.79.246
      size_download:  71273
        size_header:  537
    time_namelookup:  0.008585
       time_connect:  0.082511
    time_appconnect:  0.264110
   time_pretransfer:  0.264293
      time_redirect:  1.287257
 time_starttransfer:  3.077526
                    ----------
         time_total:  3.177939

As far as time related parameters, listed below are the ones you will most likely use –

  • time_appconnect The time, in seconds, it took from the start until the SSL/SSH/etc connect/handshake to the remote host was completed. (Added in 7.19.0)
  • time_connect The time, in seconds, it took from the start until the TCP connect to the remote host (or proxy) was completed.
  • time_namelookup The time, in seconds, it took from the start until the name resolving was completed.
  • time_pretransfer The time, in seconds, it took from the start until the file transfer was just about to begin. This includes all pre-transfer commands and negotiations that are specific to the particular protocol(s) involved.
  • time_redirect The time, in seconds, it took for all redirection steps including name lookup, connect, pretransfer and transfer before the final transaction was started. time_redirect shows the complete execution time for multiple redirections. (Added in 7.12.3)
  • time_starttransfer The time, in seconds, it took from the start until the first byte was just about to be transferred. This includes time_pretransfer and also the time the server needed to calculate the result.
  • time_total The total time, in seconds, that the full operation lasted.

References –


https://curl.haxx.se/docs/manpage.html

https://stackoverflow.com/questions/18215389/how-do-i-measure-request-and-response-times-at-once-using-curl

Error when running tree command

The tree command is a popular utility which lists the contents of a directory in a tree format, and it also allows users to specify the display depth of the directory tree. After installing the tree package in ubuntu, and running the tree command – I was getting below error:

$ tree .
sed: read error on .: Is a directory

The error doesn’t look like it is coming from the tree package just installed, after some digging I figured out that the “tree” command in this case was an alias. I use the Bash-it framework for a collection of bash commands and scripts and Bash-it has its own set of aliases including one for tree –

$ type tree
tree is aliased to `find . -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g''

In order to run the actual tree command, I had to prefix it with “command” or “\” as below –

$ command tree .
.
??? chapter-one
??? readme

1 directory, 1 file

$ \tree .
.
??? chapter-one
??? readme

1 directory, 1 file

References –

http://manpages.ubuntu.com/manpages/trusty/man1/tree.1.html

https://github.com/Bash-it/bash-it