[DRAFT] Fixes for NGINX nginx 1.23.0 

As of nginx 1.23 the cache control headers are re-implemented as al linked list.
This reworks our code that manipulates this header to work with that.

Still a draft: this change probably needs to be conditioned against nginx version
with ifdefs, so older version can still be built as well. Hence, still a draft.

Attempts to fix https://github.com/apache/incubator-pagespeed-ngx/issues/1749
diff --git a/src/ngx_pagespeed.cc b/src/ngx_pagespeed.cc
index e829560..5f19923 100644
--- a/src/ngx_pagespeed.cc
+++ b/src/ngx_pagespeed.cc
@@ -396,40 +396,32 @@
 //
 // Based on ngx_http_add_cache_control.
 ngx_int_t ps_set_cache_control(ngx_http_request_t* r, char* cache_control) {
-  // First strip existing cache-control headers.
-  ngx_table_elt_t* header;
-  NgxListIterator it(&(r->headers_out.headers.part));
-  while ((header = it.Next()) != NULL) {
-    if (STR_CASE_EQ_LITERAL(header->key, "Cache-Control")) {
-      // Response headers with hash of 0 are excluded from the response.
-      header->hash = 0;
-    }
-  }
+  ngx_table_elt_t* cc = r->headers_out.cache_control;
 
-  // Now add our new cache control header.
-  if (r->headers_out.cache_control.elts == NULL) {
-    ngx_int_t rc = ngx_array_init(&r->headers_out.cache_control, r->pool,
-                                  1, sizeof(ngx_table_elt_t*));
-    if (rc != NGX_OK) {
-      return NGX_ERROR;
-    }
+  if (cc == NULL) {
+
+      cc = reinterpret_cast<ngx_table_elt_t*>(ngx_list_push(&r->headers_out.headers));
+      if (cc == NULL) {
+          return NGX_ERROR;
+      }
+
+      r->headers_out.cache_control = cc;
+      cc->next = NULL;
+
+      cc->hash = 1;
+      ngx_str_set(&cc->key, "Cache-Control");
+
+  } else {
+      for (cc = cc->next; cc; cc = cc->next) {
+          cc->hash = 0;
+      }
+
+      cc = r->headers_out.cache_control;
+      cc->next = NULL;
   }
-  ngx_table_elt_t** cache_control_headers = static_cast<ngx_table_elt_t**>(
-      ngx_array_push(&r->headers_out.cache_control));
-  if (cache_control_headers == NULL) {
-    return NGX_ERROR;
-  }
-  cache_control_headers[0] = static_cast<ngx_table_elt_t*>(
-      ngx_list_push(&r->headers_out.headers));
-  if (cache_control_headers[0] == NULL) {
-    return NGX_ERROR;
-  }
-  cache_control_headers[0]->hash = 1;
-  ngx_str_set(&cache_control_headers[0]->key, "Cache-Control");
-  cache_control_headers[0]->value.len = strlen(cache_control);
-  cache_control_headers[0]->value.data =
+  cc->value.len = strlen(cache_control);
+  cc->value.data =
       reinterpret_cast<u_char*>(cache_control);
-
   return NGX_OK;
 }
 
@@ -439,22 +431,20 @@
   // Use headers_out.cache_control instead of looking for Cache-Control in
   // headers_out.headers, because if an upstream sent multiple Cache-Control
   // headers they're already combined in headers_out.cache_control.
-  auto ccp = static_cast<ngx_table_elt_t**>(r->headers_out.cache_control.elts);
-  if (ccp == nullptr) {
-    return false;  // Header not present.
-  }
+  ngx_table_elt_t* cc = r->headers_out.cache_control;
   bool first_segment = true;
-  for (ngx_uint_t i = 0; i < r->headers_out.cache_control.nelts; i++) {
-    if (ccp[i]->hash == 0) {
-      continue;  // Elements with a hash of 0 are marked as excluded.
+
+  while (cc != NULL) {
+    if (cc->hash) {
+      if (first_segment) {
+        first_segment = false;
+      } else {
+        cache_control->append(", ");
+      }
+      cache_control->append(reinterpret_cast<char*>(cc->value.data),
+                            cc->value.len);      
     }
-    if (first_segment) {
-      first_segment = false;
-    } else {
-      cache_control->append(", ");
-    }
-    cache_control->append(reinterpret_cast<char*>(ccp[i]->value.data),
-                          ccp[i]->value.len);
+    cc = cc->next;
   }
   return true;
 }