The Rest.li protocol specifies what HTTP method will be used for each type of Rest.li request. However, sometimes due to security constraint (i.e. not wanting to send some sensitive information in URI) or jetty buffer limitation (i.e. there may pose a threshold on the longest query that can go through), it may be required to customize the HTTP method used to send a particular Rest.li request to a Rest.li server.
Rest.li has provided ClientQueryTunnelFilter (R2 client filter) and ServerQueryTunnelFilter (R2 server filter) to support such HTTP method customization. These two filters behaves as follows:
X-HTTP-Method-Override
header. This header is important to
indicate that on the server side we should invoke QueryTunnelUtil
decoding function to get back original request so that this
conversion looks completely transparent to users. User can indicate
whether they want to perform such encoding in two ways:
requestContext.putLocalAttr(R2Constants.FORCE_QUERY_TUNNEL, true);
X-HTTP-Method-Override
.For a rest.li request without body, for example, a BATCH_GET request
like this http://localhost?ids=List(1,2,3)
, the transformed POST
request is x-www-form-urlencoded with query params stored in the body,
as follows:
curl -X POST http://localhost \
-H "X-HTTP-Method-Override: GET" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data $'ids=1,2,3'
Basically,
-X POST
)-H
"X-HTTP-Method-Override: GET"
)-H "Content-Type:
application/x-www-form-urlencoded"
)For a rest.li request with body, for example, a BATCH_UPDATE request
like this http://localhost?ids=List(1,2,3)
, the transformed POST
request will be of Content-Type of multipart/mixed with 2 sections:
It will look as follows:
curl -X POST http://localhost \
-H "X-HTTP-Method-Override: PUT" \
-H "Content-Type: multipart/mixed; boundary=xyz" \
--data $'--xyz\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\nids=List(1,2,3)\r\n--xyz\r\n
Content-Type: application/json\r\n\r\n{"foo":"bar"}\r\n--xyz--'
Here,
-X POST
)-H
"X-HTTP-Method-Override: GET"
)-H "Content-Type: multipart/mixed;
boundary=xyz"
). Note that here we need to specify a boundary
delimiter (here we use xyz
for illustration) for multipart body,
this delimiter needs to be unique and not appearing in your request
content body or url.