How to play Go Lang with HTTP

Writing Go Lang HTTP/1.1 & HTTP/2 client and server

Introduction

What is HTTP/2

Prerequisites

HTTP/1.1 Server

-----BEGIN CERTIFICATE-----
MIID+zCCAuOgAwIBAgIJAPsvGCCAC2i+MA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD
VQQGEwJMSzEQMA4GA1UECAwHV2VzdGVybjEQMA4GA1UEBwwHQ29sb21ibzESMBAG
A1UECgwJTERDTEFLTUFMMRQwEgYDVQQLDAtFbmdpbmVlcmluZzESMBAGA1UEAwwJ
bG9jYWxob3N0MSIwIAYJKoZIhvcNAQkBFhNsZGNsYWttYWxAZ21haWwuY29tMB4X
DTE5MDQyMDA1MjczM1oXDTIwMDQxOTA1MjczM1owgZMxCzAJBgNVBAYTAkxLMRAw
DgYDVQQIDAdXZXN0ZXJuMRAwDgYDVQQHDAdDb2xvbWJvMRIwEAYDVQQKDAlMRENM
QUtNQUwxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRIwEAYDVQQDDAlsb2NhbGhvc3Qx
IjAgBgkqhkiG9w0BCQEWE2xkY2xha21hbEBnbWFpbC5jb20wggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQC9PKAOlJcOBUI9CGnVjMjQHNRqYv01CaUdC4/e
YFyegxLpoMpYvEC+nYlHT2j7BOhQBV+TkH1D4YOK2WP3V0FLv5hM7Nxsgf25WNHa
zi2DTBvcBgB9sDJA/avIvF+63+Btnyggp3xq6MaHy5DNH0kPnSiPiy7PRKToEUn6
oqPnB10rRBFZqs3ePmEDxVL3T/TUZSXR3P95fV1vDCqrJbr3YwWOzFCq8kEJFslK
B7GSEKpPgmK0g5krmAQqUOuCJ3/xFlCP4trKg/lvSJZ5S/LZD5teDDg6Ax3Mvthj
kMh9/OM5GGTTjRwhct9dHjFI8POj+TMbLZvoPVXjsmATEgtLAgMBAAGjUDBOMB0G
A1UdDgQWBBQ1CmWXmrHOv6b8f763/bk80EpbajAfBgNVHSMEGDAWgBQ1CmWXmrHO
v6b8f763/bk80EpbajAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAH
D51Uoe2K4N9/GxRgww5mMW2dUJ7Hc/tGsr/J1fNqHY8SXNAn5i+GwI+xBvwxFHL3
KZHbfq7eYDE5EItt3cZp5ySSscdTEay9ReH2+8k32gpH46CMwPV3XvtQuBVVAC4u
szrq1eWKhYI2zf4iUVpwvq89OynVGIp0atng+q3A2cBhi3NGo6Ho1s2rywQyqiq8
up4PUSVQ6WBoJFx5PEEDxD84VMS7Pan6dT34b9n56tq5R06retZTUZ8jMM88CGX4
88pSPU+XImp6DdNVBmW6Lz76jiSNHLkZGm4jumjeyUGzBjBEBOgSegeWlinMtWE9
gaVxeUHrqHk8xzwJ4oIu
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC9PKAOlJcOBUI9
CGnVjMjQHNRqYv01CaUdC4/eYFyegxLpoMpYvEC+nYlHT2j7BOhQBV+TkH1D4YOK
2WP3V0FLv5hM7Nxsgf25WNHazi2DTBvcBgB9sDJA/avIvF+63+Btnyggp3xq6MaH
y5DNH0kPnSiPiy7PRKToEUn6oqPnB10rRBFZqs3ePmEDxVL3T/TUZSXR3P95fV1v
DCqrJbr3YwWOzFCq8kEJFslKB7GSEKpPgmK0g5krmAQqUOuCJ3/xFlCP4trKg/lv
SJZ5S/LZD5teDDg6Ax3MvthjkMh9/OM5GGTTjRwhct9dHjFI8POj+TMbLZvoPVXj
smATEgtLAgMBAAECggEAbaS2yDvn2cPKQTqit4y+vXY2zP1V4GkaNd4BGcOTZnRj
fOIg25EXoln8tEiadva888BpREKvkakUYlraxPDVcGIuiEOk42nd7Io97R0Q2cY7
ThxcJHb2ZxmTctdSUCBvFJTm1ySzve3pOb0ExRSfbGCOo7zs/kKzmZKK3qFlffGS
Ga9O7hyLOuXPU22CM+5Lq0JPTER73z0DpAweZc0L14j6dzhcG3qUwk0K6K47VZgE
NhEORul7xDj91bh2iEoSbaQe8HxLaMQoMXOC/9oey2UKKTe9WZE3+XCvg+vkw/sS
biQ+b4EZ9LuhAhCZ0UE6+y7PZY+8G/YsbGg0Zo8cAQKBgQDyTuG47rWBgbdHsEB/
MSKGU6w+a1SdLk6jG+Enji5Q624/h0xt5nF9ah2eRf3Rlhn9WEKM/uE9ouEODBKE
8rnIDsjufEMI8moPEloRBSsxPNw+fNMSSCZjL+qPtTJUbRio7WA23sfdnE57ygBa
wlPQ9UBBWSm2se4veEZtHjtngQKBgQDH7gnH5Att6ZYazRTgD72g0C5v1l4LYVEQ
jxdBcs6TJA8wHfifZ45F67W95QunmM813UxfS+ybdjytlb8/lmi2BnK6lDx5HWIL
31jnbg2CxCrNv9oZLjKVDmkp4WUcEp5W33R1/MGDTRfyARP+6QYQO/ATMdqtm5Uu
cD6clrL4ywKBgQCQ0niy0WmGaAMlQ8CoxLM/2c6+1+OQtlalwkoGHEKudqhELBeQ
MAVw0fW13Vtg4vfRpejQ4J26+xjMDocbEv/bBIsvjvF57XlaXLucJJy2Jwv0BSMa
cCkRa1gkYEYek74DaSzyXqDSYVO/RPKFTFRQNeUbqbD20s3rbVWablFPAQKBgB5y
zUCJJYh2w6qPQzegjhO4wOm9bxMyngL0l+ka0AUuv7VnSx8TyWIytLoX8P90UVJ1
wpTc3ksK5dDV9ot7n7ThJIXv34nehLkkKckNRLd+oro1FsUw+PkkebWsIxb0avL2
EymI9fvGOPhdW6s91/OO/VAfDpvUDxNEevSkKtujAoGAcMOsXtn/UyT3Lssxgla3
K+DCaFhAQPSUXOmpZwEbQ0yQlksDe4flsam8bEDI5D5iHx1ziSfh583qJl3BEZ5u
VZTEO2YLvT9QRz7pv2qspqj7nzSyBU2BFAajq43/G1b8FHfVgN+YdVtzVrigfql5
2a+JxOxFfpjnGQ7RfSxSb+Q=
-----END PRIVATE KEY-----
$ go run http_server.go
Go Backend: { HTTPVersion = 1 }; serving on https://localhost:9191/hello/sayHello
$ curl -k -v https://localhost:9191/hello/sayHello -d "Hello Go!"$ curl -v --cacert ./cert/server.crt https://localhost:9191/hello/sayHello -d "Hello Go!"
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 9191 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: C=LK; ST=Western; L=Colombo; O=LDCLAKMAL; OU=Engineering; CN=Chanaka Lakmal; emailAddress=ldclakmal@gmail.com
* start date: Apr 20 03:03:58 2019 GMT
* expire date: Apr 19 03:03:58 2020 GMT
* issuer: C=LK; ST=Western; L=Colombo; O=LDCLAKMAL; OU=Engineering; CN=Chanaka Lakmal; emailAddress=ldclakmal@gmail.com
* SSL certificate verify result: self signed certificate (18), continuing anyway.
> POST /hello/sayHello HTTP/1.1
> Host: localhost:9191
> User-Agent: curl/7.46.0
> Accept: */*
> Content-Length: 9
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 9 out of 9 bytes
< HTTP/1.1 200 OK
< Date: Sat, 20 Apr 2019 06:56:19 GMT
< Content-Length: 10
< Content-Type: text/plain; charset=utf-8
<
Hello Go!
* Connection #0 to host localhost left intact

HTTP/1.1 Client

$ go run http_client.go
Got response 200: HTTP/1.1 Hello Go!
$ curl -v --cacert ./cert/server.crt https://localhost:9191/hello/sayHello -d "Hello Go!"

HTTP/2 Server

$ go run http2_server.go
Go Backend: { HTTPVersion = 2 }; serving on https://localhost:9191/hello/sayHello
$ curl -k -v https://localhost:9191/hello/sayHello -d "Hello Go!"$ curl -v --cacert ./cert/server.crt https://localhost:9191/hello/sayHello -d "Hello Go!"
$ curl -k -v --http2 https://localhost:9191/hello/sayHello -d "Hello Go!"$ curl -v --http2 --cacert ./cert/server.crt https://localhost:9191/hello/sayHello -d "Hello Go!"
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 9191 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: src/hello/cert/server.crt
CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: C=LK; ST=Western; L=Colombo; O=LDCLAKMAL; OU=Engineering; CN=localhost; emailAddress=ldclakmal@gmail.com
* start date: Apr 20 05:27:33 2019 GMT
* expire date: Apr 19 05:27:33 2020 GMT
* common name: localhost (matched)
* issuer: C=LK; ST=Western; L=Colombo; O=LDCLAKMAL; OU=Engineering; CN=localhost; emailAddress=ldclakmal@gmail.com
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* TCP_NODELAY set
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x10ddf20)
> POST /hello/sayHello HTTP/1.1
> Host: localhost:9191
> User-Agent: curl/7.46.0
> Accept: */*
> Content-Length: 9
> Content-Type: application/x-www-form-urlencoded
>
* We are completely uploaded and fine
< HTTP/2.0 200
< content-type:text/plain; charset=utf-8
< content-length:10
< date:Sat, 20 Apr 2019 06:54:50 GMT
<
Hello Go!
* Connection #0 to host localhost left intact

HTTP/2 Client

$ go run http2_client.go
Got response 200: HTTP/2 Hello Go!
$ curl -v --http2 --cacert ./cert/server.crt https://localhost:9191/hello/sayHello -d "Hello Go!"

Happy coding with Go !

References

Tech Enthusiast | Software Engineer @ WSO2 | Computer Science Engineering @ UoM | Rotaractor | Maliyadeva College

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store