# Remove meta from reply\_html\_page

**URL:** <https://swi-prolog.discourse.group/t/remove-meta-from-reply-html-page/4189>\
**Category:** Pack\
**Tags:** http, framework-benchmarks\
**Created:** [July 23, 2021, 10:11am UTC](https://swi-prolog.discourse.group/t/remove-meta-from-reply-html-page/4189 "2021-07-23T10:11:32Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![\_vka](https://avatars.discourse-cdn.com/v4/letter/_/96bed5/32.png) [@\_vka](https://swi-prolog.discourse.group/u/_vka)\
**Post date:** [July 23, 2021, 10:11am UTC](https://swi-prolog.discourse.group/t/remove-meta-from-reply-html-page/4189/1 "2021-07-23T10:11:32Z")

</div>

Hello,

I am working on updating the SWI-Prolog entry to FrameworkBenchmark: [FrameworkBenchmarks/frameworks/Prolog/SWI-Prolog at master · TechEmpower/FrameworkBenchmarks · GitHub](https://github.com/TechEmpower/FrameworkBenchmarks/tree/master/frameworks/Prolog/SWI-Prolog)

According to the FrameworkBenchmark’s specification, the endpoint `/fortunes` should respond with a very specific response. For one, the head cannot have a `meta` tag. Also, the endpoint must send back `Content-Length` header. Hence my questions.

Question 1: How do I remove the `meta` tag that is automatically inserted by `reply_html_page` ?

```prolog
reply_html_page(
    [title('Fortunes')],
    [table([
        ...
    ])]
).

```

The generated code looks like this:

```prolog
<!DOCTYPE html>
<HTML>
  <head>
    <title>Fortunes</title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body>
    ...
  </body>
</html>

```

Question 2: Is there a way to send the `Content-Length` header with the response generated by `reply_html_page`?

Question 3: As I am new to Prolog, I will appreciate any feedback on the code in question.

Cross-Post: [prolog - Remove meta from reply\_html\_page - Stack Overflow](https://stackoverflow.com/questions/68493300/remove-meta-from-reply-html-page)

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [July 23, 2021, 10:44am UTC](https://swi-prolog.discourse.group/t/remove-meta-from-reply-html-page/4189/2 "2021-07-23T10:44:34Z")

</div>

I will take a look but am just learning this stuff myself so no promises on an answer.

The tutorial by Anne is one of the best for learning about [Creating Web Applications in SWI-Prolog](https://github.com/Anniepoo/swiplwebtut/blob/07b42b1e7eac000d9eeac959ba2a38a616fd4b9b/web.adoc) and might be of help.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [July 23, 2021, 11:30am UTC](https://swi-prolog.discourse.group/t/remove-meta-from-reply-html-page/4189/3 "2021-07-23T11:30:21Z")

</div>

> [@\_vka](#):
>
> For one, the head cannot have a `meta` tag.

I find that to be confusing. One of the points of the meta tag is to have the content type so that the specification of the page is known, think syntax checking or even at times type checking. reply\_html\_page/2 makes some knowledge of the content type.

So I am thinking that if there is no content type then reply\_html\_page/2 should not be used and something at a lower level from SWI-Prolog should be used in constructing the response. 🤔

If that is the case then also should not an entire Prolog module be created similar to reply\_html\_page/2 that knows of the specifics of the response needed for `/fortunes`? [library(quasi\_quotations): Define Quasi Quotation syntax](https://www.swi-prolog.org/pldoc/man?section=quasiquotations) comes to mind, See: [Is there a way to go from HTML to the Prolog representation of the HTML?](https://swi-prolog.discourse.group/t/is-there-a-way-to-go-from-html-to-the-prolog-representation-of-the-html/2901)

The reason I state this is that in reading about [html\_set\_options/1](https://www.swi-prolog.org/pldoc/doc_for?object=html_write%3Ahtml_set_options/1) with `content_type(+ContentType)` it seems that removing the meta tag for reply\_html\_page/2 is not something that should be done.

```prolog
Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.27)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- html_current_option(Option).
ERROR: Unknown procedure: html_current_option/1 (DWIM could not correct goal)

?- use_module(library(http/html_write)).
true.

?- html_current_option(Option).
Option = dialect(html5) ;
Option = doctype(html) ;
Option = content_type('text/html; charset=UTF-8').

```

---

<div class="post-metadata">

**Author:** ![\_vka](https://avatars.discourse-cdn.com/v4/letter/_/96bed5/32.png) [@\_vka](https://swi-prolog.discourse.group/u/_vka)\
**Post date:** [July 23, 2021, 12:04pm UTC](https://swi-prolog.discourse.group/t/remove-meta-from-reply-html-page/4189/4 "2021-07-23T12:04:04Z")

</div>

> [@EricGT](#):
>
> library(quasi\_quotations): Define Quasi Quotation syntax

Thanks, is there an example for `quasi_quotations` explaining how to use it with lists, Unicode and HTML entities? Are those handled transparently?

More specifically I need to get from something like:

```prolog
Rows = [row(1, 'こんにちは'), row(2, '<alert>Good bye</alert>')]

```

to

```html
<html>
<head><title>Fortunes</title></head>
<body>
<table>
  <tr>
    <td>1</td>
    <td>こんにちは</td>
  </tr>
  <tr>
    <td>2</td>
    <td>&lt;alert&gt;Good bye&lt;/alert&gt;</td>
   </tr>
</table>
</body>
</html>

```

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [July 23, 2021, 12:18pm UTC](https://swi-prolog.discourse.group/t/remove-meta-from-reply-html-page/4189/5 "2021-07-23T12:18:21Z")

</div>

> [@\_vka](#):
>
> For one, the head cannot have a `meta` tag

Very odd … Reading the source, something along these lines should work (not tested and you must fill in the …):

```prolog
reply(_Request) :-
    phrase(page([head(...), body(...)]), Tokens),
    print_html(Tokens).

```

Question 2: Is there a way to send the `Content-Length` header with the response generated by `reply_html_page` ?

The content length is added by the HTTP server.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [July 23, 2021, 12:21pm UTC](https://swi-prolog.discourse.group/t/remove-meta-from-reply-html-page/4189/6 "2021-07-23T12:21:41Z")

</div>

Before writing code based on your example is the only thing that is likely to change the row elements?

The reason I ask is that while quasiquotations will work, they might be overkill.

For the static part using DCGs, format/2 or even simple unification of a variable into an atom using atomic\_list\_concat/2 might be better.

For generating the table I am thinking something like apropos\_rows/1 from [Examples for using the HTML write library](https://www.swi-prolog.org/pldoc/man?section=html-write-examples).

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [July 23, 2021, 12:32pm UTC](https://swi-prolog.discourse.group/t/remove-meta-from-reply-html-page/4189/8 "2021-07-23T12:32:00Z")

</div>

Here is something that works:

```prolog
:- use_module(library(http/http_server)).
:- use_module(library(http/html_write)).
:- use_module(library(dcg/high_order)).

run :-
    http_server([port(8080)]).

:- http_handler(root(.), reply, []).

reply(_Request) :-
    findall(row(N,C), row(N,C), Rows),
    phrase(page([ head(title('Fortunes')),
                  body(table(\sequence(row, Rows)))
                ]),
           Tokens),
    format('Content-type: text/html~n~n'),
    print_html(Tokens).

row(row(N, C)) -->
    html(tr([td(N), td(C)])).

% data
row(1, 'こんにちは').
row(2, '<alert>Good bye</alert>').

```

And here is the output:

```prolog
$ curl -D hdr http://localhost:8080/
<!DOCTYPE html>
<html>
<head>
<title>Fortunes</title>

</head>
<body>

<table>
<tr><td>1</td><td>こんにちは</td></tr>
<tr><td>2</td><td>&lt;alert&gt;Good bye&lt;/alert&gt;</td></tr>
</table>

</body>
</html>

```

```prolog
$ cat hdr
HTTP/1.1 200 OK
Date: Fri, 23 Jul 2021 12:30:22 GMT
Content-Type: text/html; charset=UTF-8
Connection: Keep-Alive
Content-Length: 213

```

Edit: may require 8.3.x. Not sure when sequence//2 was added to the library.

---

<div class="post-metadata">

**Author:** ![\_vka](https://avatars.discourse-cdn.com/v4/letter/_/96bed5/32.png) [@\_vka](https://swi-prolog.discourse.group/u/_vka)\
**Post date:** [July 23, 2021, 1:57pm UTC](https://swi-prolog.discourse.group/t/remove-meta-from-reply-html-page/4189/9 "2021-07-23T13:57:20Z")

</div>

> [@EricGT](#):
>
> Before writing code based on your example is the only thing that is likely to change are the row elements?

Yes, the only thing coming from the DB are the rows. The rest is static.

To clarify, in FrameworkBenchmark there are plenty of submissions out there that are trying to squeeze every last drop of performance out of respective platforms with the sole goal of winning the benchmark. I think such submissions miss the point somewhat. The idea of the FrameworkBenchmark is not to produce the fastest code (i.e. just use rust/c++, why bother?) but to show the platform’s idiomatic way of solving a predefined set of test problems, and to weigh readability, elegance, structure, patterns etc. against performance penalty.

---

<div class="post-metadata">

**Author:** ![\_vka](https://avatars.discourse-cdn.com/v4/letter/_/96bed5/32.png) [@\_vka](https://swi-prolog.discourse.group/u/_vka)\
**Post date:** [July 23, 2021, 1:58pm UTC](https://swi-prolog.discourse.group/t/remove-meta-from-reply-html-page/4189/10 "2021-07-23T13:58:59Z")

</div>

> [@jan](#):
>
> Here is something that works:

It does. Thank you very much!

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [July 23, 2021, 1:59pm UTC](https://swi-prolog.discourse.group/t/remove-meta-from-reply-html-page/4189/11 "2021-07-23T13:59:46Z")

</div>

> [@\_vka](#):
>
> FrameworkBenchmark

That is a concept that is foreign to me and maybe others here.

Is this a correct link?

> **[TechEmpower Web Framework Performance Comparison](https://www.techempower.com/benchmarks/)**
>
> Performance comparison of a wide spectrum of web application frameworks and platforms using community-contributed test implementations.

---

<div class="post-metadata">

**Author:** ![\_vka](https://avatars.discourse-cdn.com/v4/letter/_/96bed5/32.png) [@\_vka](https://swi-prolog.discourse.group/u/_vka)\
**Post date:** [July 23, 2021, 2:03pm UTC](https://swi-prolog.discourse.group/t/remove-meta-from-reply-html-page/4189/12 "2021-07-23T14:03:36Z")

</div>

> [@EricGT](#):
>
> Is this a correct link?

It is. Here are few more:

- The main page: [TechEmpower Framework Benchmarks](https://www.techempower.com/benchmarks/)
- Test types: [Project Information Framework Tests Overview · TechEmpower/FrameworkBenchmarks Wiki · GitHub](https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview)
- Continuous benchmark results: [https://tfb-status.techempower.com/](https://tfb-status.techempower.com/)

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [July 23, 2021, 2:51pm UTC](https://swi-prolog.discourse.group/t/remove-meta-from-reply-html-page/4189/15 "2021-07-23T14:51:32Z")

</div>

> [@anon95304481](#):
>
> Isn’t dynamic content sent chunked?

That depends on some conditions. I don’t recall the details, but yes, `Transfer-encoding: chunked` is supported.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [July 23, 2021, 4:07pm UTC](https://swi-prolog.discourse.group/t/remove-meta-from-reply-html-page/4189/17 "2021-07-23T16:07:05Z")

</div>

> [@\_vka](#):
>
> I am working on updating the [SWI-Prolog](https://www.swi-prolog.org/pldoc/doc_for?object=manual) entry to FrameworkBenchmark: [FrameworkBenchmarks/frameworks/Prolog/SWI-Prolog at master · TechEmpower/FrameworkBenchmarks · GitHub](https://github.com/TechEmpower/FrameworkBenchmarks/tree/master/frameworks/Prolog/SWI-Prolog)

The code uses a PostgreSQL database.

> <https://github.com/TechEmpower/FrameworkBenchmarks/blob/5282196ce481110515003d87f1f41eb23023c24d/frameworks/Prolog/SWI-Prolog/app/database.pl#L45-L46>

Prolog is [homoiconic](https://en.wikipedia.org/wiki/Homoiconicity) so by many in the Prolog community Prolog is also the database.

Is FrameworksBenchmarks requiring that another database be used? If so how much data is being stored? One can store a lot in Prolog without needing another SQL or NoSQL database. ([ref](https://swi-prolog.discourse.group/t/quick-load-files/1239/4))

If the data can be stored with SWI-Prolog using [library(persistency)](https://www.swi-prolog.org/pldoc/man?section=persistency) then I would personally consider that they are saddling Prolog with an artificial constraint and that any results for Prolog should not be considered valid. I do understand that there are times when the data is an external database and so Prolog needs to access it as such but if given the choice of using Prolog as the database and using Prolog with an another database I will choose using Prolog as the database. 🙂

---

<div class="post-metadata">

**Author:** ![\_vka](https://avatars.discourse-cdn.com/v4/letter/_/96bed5/32.png) [@\_vka](https://swi-prolog.discourse.group/u/_vka)\
**Post date:** [July 23, 2021, 11:04pm UTC](https://swi-prolog.discourse.group/t/remove-meta-from-reply-html-page/4189/18 "2021-07-23T23:04:20Z")

</div>

> [@EricGT](#):
>
> I would personally consider that they are saddling Prolog with an artificial constraint

I wouldn’t see it that way. This is a benchmark for web apps, and these days the web apps almost exclusively distributed, cloud based, with stateless web fronts and a managed database behind, acting as source of truth.

In fact, if you wish to suffer some philosophising on my side, I’d say emphasis on:

- docker
- serverless
- integration (with other managed services like DBs, cache fronts, cloud APIs, message queues)
- monitoring

is the best option for Prolog to see more adoption.

But this is a completely separate discussion I am not fully equipped to have right now.

---

<div class="post-metadata">

**Author:** ![\_vka](https://avatars.discourse-cdn.com/v4/letter/_/96bed5/32.png) [@\_vka](https://swi-prolog.discourse.group/u/_vka)\
**Post date:** [July 23, 2021, 11:40pm UTC](https://swi-prolog.discourse.group/t/remove-meta-from-reply-html-page/4189/19 "2021-07-23T23:40:16Z")

</div>

Not sure why, but I received emails with replies from Mostowski Collapse, but I don’t see any of them here. Nonetheless, I’d like to address a comment about HTTP/2 in one of them:

The FB is a GCD among way too many different frameworks. It’s not perfect, no doubt. But moving such a huge blob forward is a monumental job. In any case, HTTP/2 tests are in the pipeline:

> <https://github.com/TechEmpower/FrameworkBenchmarks/issues/5784>
>
> Current benchmarks use wrk which isn't HTTP2 capable even though many frameworks… support HTTP2.
> 
> In my opinion not using HTTP2 presents a problem: if X is faster than Y according to the benchmarks, would X be faster than Y if both of them used HTTP2 instead? what if Y was optimized for HTTP2 like h2o for example?.
> 
> The obstacle I see besides replacing wrk is that not all frameworks support HTTP2, I suggest we use HTTP2 where possible, benchmarking tool should fallback to HTTP1.1 if server doesn't support it, and last but not least the Results Website should show - preferably in a NEW column - the HTTP Protocol version used in the benchmark.
> 
> For the benchmarking tool we can choose from:
> 1- \[Hay\](https://github.com/rakyll/hey)
> 2- \[Vageta\](https://github.com/tsenart/vegeta)

---

<div class="post-metadata">

**Author:** ![\_vka](https://avatars.discourse-cdn.com/v4/letter/_/96bed5/32.png) [@\_vka](https://swi-prolog.discourse.group/u/_vka)\
**Post date:** [July 24, 2021, 12:02am UTC](https://swi-prolog.discourse.group/t/remove-meta-from-reply-html-page/4189/20 "2021-07-24T00:02:22Z")

</div>

I’ve added a short how-to about FB, in case you feel like contributing: [What is FrameworkBenchmark and how to contribute](https://swi-prolog.discourse.group/t/what-is-frameworkbenchmark-and-how-to-contribute/4193)
