<rest:response> - unclear strategy of setting header during serialization

Saturday, 14 July 2018 · 5 messages
BB
Bogdan Bogucki14 Jul 2018 11:30 #

Hello,

I encountered strange behavior during HTTP response.

I need to set custom header Access-Control-Allow-Origin:*.

To do that I am using custom response.

Following code is working and set required header:

declare

%rest:POST("{$json}")

%rest:path("/ping")

function drpg:ping(

$json as xs:string

) as element()* {

  <rest:response>

    <http:response status="200" message="OK">

      <http:header name="Access-Control-Allow-Origin" value="*"/>

      <http:header name="Content-Type" value="text/html"/>

    </http:response>

  </rest:response>,

  let $p := json:parse($json)

return ($p/json/data/_/_/_)[last()]

};

Response header:

Access-Control-Allow-Origin

*

Content-Length

11

Content-Type

text/html;charset=utf-8

Date

Sat, 14 Jul 2018 09:17:18 GMT

Server

Jetty(9.4.9.v20180320)

I want to return plain text, so when I change return parameter to xs:string* and add data function header from <rest:response> is overwritten.

Response header:

Content-Length

6

Content-Type

application/xml; charset=UTF-8

Date

Sat, 14 Jul 2018 09:26:59 GMT

Server

Jetty(9.4.9.v20180320)

Example code:

declare

%rest:POST("{$json}")

%rest:path("/drpg/ping")

function drpg:ping(

$json as xs:string

) as xs:string* {

  <rest:response>

    <http:response status="200" message="OK">

      <http:header name="Access-Control-Allow-Origin" value="*"/>

      <http:header name="Content-Type" value="text/html"/>

    </http:response>

  </rest:response>,

  let $p := json:parse($json)

return data(($p/json/data/_/_/_)[last()])

};

Why does header is overwritten ? I think if header is set explicitly it shouldn't be overwritten.

Best Regards Bogdan Bogucki

CG
Christian Grün14 Jul 2018 11:44 #

Hi Bogdan,

If you change the return type of an XQuery function to xs:string, your nodes will be implicitly converted to strings:

  declare function local:f() as xs:string {
    <a>X</a>
  };
  (: will result in 'X' :)
  local:f()

The string conversion of your http:response element yields an empty string, so it does not matter what you specify as attribute values.

If you want to return text/plain, you’ll have to change your content type from text/html to to text/plain:

  <http:header name="Content-Type" value="text/plain"/>

Best, Christian

Quoted text · Bogdan Bogucki · 155 lines
On Sat, Jul 14, 2018 at 11:30 AM Bogdan Bogucki <bbogucki at hussar.pl> wrote: > Hello, > > > > I encountered strange behavior during HTTP response. > > > > I need to set custom header Access-Control-Allow-Origin:*. > > > > To do that I am using custom response. > > > > Following code is working and set required header: > > > > declare > > %rest:POST("{$json}") > > %rest:path("/ping") > > function drpg:ping( > > $json as xs:string > > ) as element()* { > > ​​ > <rest:response> > > <http:response status="200" message="OK"> > > <http:header name="Access-Control-Allow-Origin" value="*"/> > > ​​ > <http:header name="Content-Type" value="text/html"/> > > </http:response> > > </rest:response>, > > let $p := json:parse($json) > > return ($p/json/data/_/_/_)[last()] > > }; > > > > Response header: > > Access-Control-Allow-Origin > > * > > > > Content-Length > > 11 > > Content-Type > > text/html;charset=utf-8 > > Date > > Sat, 14 Jul 2018 09:17:18 GMT > > Server > > Jetty(9.4.9.v20180320) > > > > I want to return plain text, so when I change return parameter to > xs:string* and add data function header from <rest:response> is > overwritten. > > > > Response header: > > Content-Length > > 6 > > > > Content-Type > > application/xml; charset=UTF-8 > > Date > > Sat, 14 Jul 2018 09:26:59 GMT > > Server > > Jetty(9.4.9.v20180320) > > > > Example code: > > declare > > %rest:POST("{$json}") > > %rest:path("/drpg/ping") > > function drpg:ping( > > $json as xs:string > > ) as xs:string* { > > <rest:response> > > <http:response status="200" message="OK"> > > <http:header name="Access-Control-Allow-Origin" value="*"/> > > <http:header name="Content-Type" value="text/html"/> > > </http:response> > > </rest:response>, > > let $p := json:parse($json) > > return data(($p/json/data/_/_/_)[last()]) > > }; > > > > Why does header is overwritten ? I think if header is set explicitly it > shouldn't be overwritten. > > > > Best Regards > Bogdan Bogucki > > > > >
BB
Bogdan Bogucki14 Jul 2018 13:22 #

Hello,

declare

%rest:POST("{$json}")

%rest:path("/drpg/ping")

function drpg:ping(

$json as xs:string

) as xs:string* {

  <rest:response>

    <http:response status="200" message="OK">

      <http:header name="Access-Control-Allow-Origin" value="*"/>

      <http:header name="Content-Type" value="text/plain"/>

    </http:response>

  </rest:response>,

  let $p := json:parse($json)

return ($p/json/data/_/_/_)[last()]

};

Element was converted to string but header is overwritten.

Response header:

Content-Length: 6

Content-Type: application/xml; charset=UTF-8

Date: Sat, 14 Jul 2018 11:14:32 GMT

Server: Jetty(9.4.9.v20180320)

How can I set <http:header name="Access-Control-Allow-Origin" value="*"/> ?

Why when return type is element() header is set correctly ?

Access-Control-Allow-Origin : *

Content-Length : 11

Content-Type: text/plain;charset=utf-8

Date: Sat, 14 Jul 2018 11:18:43 GMT

Server: Jetty(9.4.9.v20180320)

Pozdrawiam Bogdan Bogucki

HUSSAR SYSTEMS

NIP: 532-170-12-00

Regon: 142624070

e-mail: <mailto:bbogucki at hussar.pl> bbogucki at hussar.pl tel. kom.: +48 607 409 301 www: <http://www.hussar.pl/> www.hussar.pl

Od: Christian Grün [mailto:christian.gruen at gmail.com] Wysłano: 14 lipca 2018 11:45 Do: Bogdan Bogucki DW: BaseX Temat: Re: [basex-talk] <rest:response> - unclear strategy of setting header during serialization

Hi Bogdan,

If you change the return type of an XQuery function to xs:string, your nodes will be implicitly converted to strings:

  declare function local:f() as xs:string {

    <a>X</a>

};

(: will result in 'X' :)

  local:f()

The string conversion of your http:response element yields an empty string, so it does not matter what you specify as attribute values.

If you want to return text/plain, you’ll have to change your content type from text/html to to text/plain:

  <http:header name="Content-Type" value="text/plain"/>

Best, Christian

Quoted text · Bogdan Bogucki · 1 line
On Sat, Jul 14, 2018 at 11:30 AM Bogdan Bogucki <bbogucki at hussar.pl> wrote:

Hello,

I encountered strange behavior during HTTP response.

I need to set custom header Access-Control-Allow-Origin:*.

To do that I am using custom response.

Following code is working and set required header:

declare

%rest:POST("{$json}")

%rest:path("/ping")

function drpg:ping(

$json as xs:string

) as element()* {

​​

  <rest:response>

    <http:response status="200" message="OK">

      <http:header name="Access-Control-Allow-Origin" value="*"/>

​​

      <http:header name="Content-Type" value="text/html"/>

    </http:response>

  </rest:response>,

  let $p := json:parse($json)

return ($p/json/data/_/_/_)[last()]

};

Response header:

Access-Control-Allow-Origin

*

Content-Length

11

Content-Type

text/html;charset=utf-8

Date

Sat, 14 Jul 2018 09:17:18 GMT

Server

Jetty(9.4.9.v20180320)

I want to return plain text, so when I change return parameter to xs:string* and add data function header from <rest:response> is overwritten.

Response header:

Content-Length

6

Content-Type

application/xml; charset=UTF-8

Date

Sat, 14 Jul 2018 09:26:59 GMT

Server

Jetty(9.4.9.v20180320)

Example code:

declare

%rest:POST("{$json}")

%rest:path("/drpg/ping")

function drpg:ping(

$json as xs:string

) as xs:string* {

  <rest:response>

    <http:response status="200" message="OK">

      <http:header name="Access-Control-Allow-Origin" value="*"/>

      <http:header name="Content-Type" value="text/html"/>

    </http:response>

  </rest:response>,

  let $p := json:parse($json)

return data(($p/json/data/_/_/_)[last()])

};

Why does header is overwritten ? I think if header is set explicitly it shouldn't be overwritten.

Best Regards Bogdan Bogucki

CG
Christian Grün14 Jul 2018 13:25 #
Quoted text · Bogdan Bogucki · 4 lines
> > If you change the return type of an XQuery function to xs:string, your > nodes will be implicitly converted to strings. >

This is the standard behavior of XQuery and no particular feature of RESTXQ. Play around with the query that I presented in my previous answer.

You need to remove the xs:string* return typeb you can replace it with item()*.

BB
Bogdan Bogucki14 Jul 2018 20:47 #

Hello CHristian,

Thank you for help. Understood.

Structure <rest:response> was serialized to empty string. Now It is clear for me why data is lost.

Best Regards Bogdan Bogucki

Od: Christian Grün [mailto:christian.gruen at gmail.com] Wysłano: 14 lipca 2018 13:25 Do: Bogdan Bogucki DW: BaseX Temat: Re: [basex-talk] <rest:response> - unclear strategy of setting header during serialization

If you change the return type of an XQuery function to xs:string, your nodes will be implicitly converted to strings.

This is the standard behavior of XQuery and no particular feature of RESTXQ. Play around with the query that I presented in my previous answer.

You need to remove the xs:string* return typeb you can replace it with item()*.


⚡Generated with XQuery