Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't convert to JSON when calling a function which returns text and sets Content-Type as non-json #2138

Closed
nileshtrivedi opened this issue Jan 25, 2022 · 2 comments
Labels

Comments

@nileshtrivedi
Copy link
Contributor

Environment

  • PostgreSQL version: 14
  • PostgREST version: 9.0.0
  • Operating system: Mac OS (Apple Silicon)

Description of issue

I wanted to serve the base HTML page directly from postgrest. So, I created a postgresql function that returns text and sets Content-Type header to text/html like this:

CREATE OR REPLACE FUNCTION todo.homepage() RETURNS varchar AS $$
BEGIN
  PERFORM set_config('response.headers','[{"Content-Type": "text/html"}]', true);
  RETURN '<html><body>Hello</body></html>';
END;
$$ LANGUAGE plpgsql IMMUTABLE;

And then I expected, the HTML to be returned at /rpc/homepage:

$ curl -v http://localhost:3000/rpc/homepage
*   Trying ::1:3000...
* connect to ::1 port 3000 failed: Connection refused
*   Trying 127.0.0.1:3000...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /rpc/homepage HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.77.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
< Date: Mon, 24 Jan 2022 23:46:47 GMT
< Server: postgrest/9.0.0
< Content-Range: 0-0/*
< Content-Type: text/html
< 
* Connection #0 to host localhost left intact
"<html><body>Hello</body></html>"%

As you can see, the function's returned value was string which was converted to JSON and hence it includes double-quotes. This was not expected, as I head set the content-type to be text/html instead of application/json.

Another unexpected behavior was the trailing % in the response body.

Possibly related issues:

What am I trying to achieve and what are my constraints:

I'm trying to ship an on-premise webapp with SQL+JS stack. Essentially, we will give users an SQL script to run which defines the models and functions, postgREST would both provide CRUD apis as well as serve the base HTML page. The page would then load JS/CSS files from CDN which are published and maintained by developers.

Workaround

@laurenceisla suggested in Gitter chat that I inject an Accept: text/plain header using nginx rewrite rules like this:

location ~ ^/html/(.*) {
    proxy_set_header Accept 'text/plain';
    proxy_pass http://localhost:3000/rpc/$1;
}

And then http://localhost/html/homepage should return the HTML ready for browser's consumption.

But IMHO, it still seems wrong for postgrest to force a conversion to JSON when the function explicitly sets a content-type as non-JSON.

@wolfgangwalther
Copy link
Member

You might want to look into the raw-media-types config option: https://postgrest.org/en/stable/configuration.html#raw-media-types.

You should be able to set it to raw-media-types="text/html" to achieve this.

This is even covered in a test-case:

spec = describe "When raw-media-types is set to \"text/html\"" $
it "can get raw output with Accept: text/html" $
request methodGet "/rpc/welcome.html" (acceptHdrs "text/html") ""
`shouldRespondWith`
[str|
|<html>
| <head>
| <title>PostgREST</title>
| </head>
| <body>
| <h1>Welcome to PostgREST</h1>
| </body>
|</html>
|]
{ matchStatus = 200
, matchHeaders = ["Content-Type" <:> "text/html"]
}

@nileshtrivedi
Copy link
Contributor Author

@wolfgangwalther This is perfect! Thank you.

nileshtrivedi added a commit to nileshtrivedi/postgrest-docs that referenced this issue Jan 25, 2022
[I ran into a gotcha](PostgREST/postgrest#2138). Improving docs so that others can avoid this.

My first PR in this project, and I haven't tested the generated docs. Feel free to discard if it's not appropriate or not done correctly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants