Home A simple Worker to display Cloudflare headers
Post
Cancel

A simple Worker to display Cloudflare headers

This post shows how to create a simple worker that displays Cloudflare headers.

  1. Create a new project using wrangler wrangler init cf-header.

  2. Using your preferred code editor, modify ./src/index.ts as follows.

    Note: The Cloudflare Request interface is documented here: Request.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    
     /**
      * Welcome to Cloudflare Workers! This is your first worker.
     *
     * - Run `wrangler dev src/index.ts` in your terminal to start a development server
     * - Open a browser tab at http://localhost:8787/ to see your worker in action
     * - Run `wrangler publish src/index.ts --name my-worker` to publish your worker
     *
     * Learn more at https://developers.cloudflare.com/workers/
     */
    
     export default {
       async fetch(request: Request): Promise<Response> {
         // Cloudflare Properties
         const CfProperties = request.cf
    
         // Request Headers
         var reqHeaders: any = {}
         for (const key of request.headers.keys()) {
           let a = key.toString()
           reqHeaders[key] = request.headers.get(key)
         }
    
         return new Response(JSON.stringify({
           "CfProperties": CfProperties,
           "RequestHeaders": reqHeaders
         }, null, 2));
       },
     };
    
  3. Test and Publish your worker using wrangler dev and wrangler publish.

  4. To see all Cloudflare headers, you need to add a custom domain to the Worker. You do this in the Cloudflare dashboard > Account Home > Workers > your Worker > Triggers > Custom Domains.

  5. Navigate to the worker cf-header.yourdomain. The output will look like the following.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    
     {
       "CfProperties": {
         "clientTcpRtt": 7,
         "longitude": "<redacted>",
         "latitude": "<redacted>",
         "tlsCipher": "AEAD-AES128-GCM-SHA256",
         "continent": "OC",
         "asn": "<redacted>",
         "clientAcceptEncoding": "gzip, deflate, br",
         "country": "AU",
         "tlsClientAuth": {
           "certIssuerDNLegacy": "",
           "certIssuerSKI": "",
           "certSubjectDNRFC2253": "",
           "certSubjectDNLegacy": "",
           "certFingerprintSHA256": "",
           "certNotBefore": "",
           "certSKI": "",
           "certSerial": "",
           "certIssuerDN": "",
           "certVerified": "NONE",
           "certNotAfter": "",
           "certSubjectDN": "",
           "certPresented": "0",
           "certRevoked": "0",
           "certIssuerSerial": "",
           "certIssuerDNRFC2253": "",
           "certFingerprintSHA1": ""
         },
         "tlsExportedAuthenticator": {
           "clientFinished": "80da6df49bf69e60c64e9ec5ccacc6ea8e0f607918b4d1245561074da70fda15",
           "clientHandshake": "a74a7f73f879d5235ba754e9732f6d5acdc7fb1fce50c16c1d60a3b27dbe85a1",
           "serverHandshake": "0eea3a4aacf97bd0cef7c0a6a693b691d8c03de44ae0d526ee66c182ea38d1c6",
           "serverFinished": "078ce079e5bc5b4349fc51cdbb218d53097b5dc1c9cdda15645e951bf5c4d3f1"
         },
         "tlsVersion": "TLSv1.3",
         "colo": "SYD",
         "timezone": "Australia/Sydney",
         "city": "<redacted>",
         "httpProtocol": "HTTP/2",
         "edgeRequestKeepAliveStatus": 1,
         "requestPriority": "weight=256;exclusive=1",
         "botManagement": {
           "corporateProxy": false,
           "verifiedBot": false,
           "ja3Hash": "cd08e31494f9531f560d64c695473da9",
           "staticResource": false,
           "score": 99
         },
         "clientTrustScore": 99,
         "region": "<redacted>",
         "regionCode": "<redacted>",
         "asOrganization": "<redacted>",
         "postalCode": "<redacted>"
       },
       "RequestHeaders": {
         "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
         "accept-encoding": "gzip",
         "accept-language": "en-US,en;q=0.9",
         "cf-connecting-ip": "<redacted>",
         "cf-ipcountry": "AU",
         "cf-ray": "7638d33dbc15a894",
         "cf-visitor": "{\"scheme\":\"https\"}",
         "connection": "Keep-Alive",
         "cookie": "__cf_bm=mmJ0FiLNxEKkKnwCBFcTwzeEyLxiV56m4ox4mqCNaIg-1667348698-0-ARj47UomevLNr4fnqvMYKwHAUJmdkrmwdtbi3tyHBmx3Q6FnLaoElIZDR73IXfHp9toaW34oDqtl8OnO8k2bphDyhjluTfI/KfqwT/qYkts4GRcJKnpY7aNZHWsaIF4GhaIvVZn2F+NK0KDQXpwfES7tiwLN8/WpUcqQJ0ZlcRQl",
         "host": "cf-headers.<redacted>",
         "sec-ch-ua": "\"Chromium\";v=\"106\", \"Google Chrome\";v=\"106\", \"Not;A=Brand\";v=\"99\"",
         "sec-ch-ua-mobile": "?0",
         "sec-ch-ua-platform": "\"macOS\"",
         "sec-fetch-dest": "document",
         "sec-fetch-mode": "navigate",
         "sec-fetch-site": "none",
         "sec-fetch-user": "?1",
         "upgrade-insecure-requests": "1",
         "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36",
         "x-forwarded-proto": "https",
         "x-real-ip": "<redacted>"
       }
     }
    
This post is licensed under CC BY 4.0 by the author.