rexyai / RestRserve

R web API framework for building high-performance microservices and app backends
https://restrserve.org
275 stars 32 forks source link

Compression example and web browser #112

Closed mattjvincent closed 4 years ago

mattjvincent commented 4 years ago

I am using your compression example:

RestRserve/inst/examples/compression/app.R

Once this is run, RCurl works fine.

However, attempting to use a web browser, fails. Firefox throws:

Content Encoding Error

The page you are trying to view cannot be shown because it uses an invalid or unsupported form of compression.

I also tried getting data from a Python script utilizing the requests library.

import requests
r = requests.get('http://127.0.0.1:8001/hello')

And I get an error:

ContentDecodingError: ('Received response with content-encoding: gzip, but failed to decode it.', error('Error -3 while decompressing data: incorrect header check',))

Any help or pointers would be greatly appreciated.

mattjvincent commented 4 years ago

After reviewing memCompress, I see that it does not add the gzip headers.

> memCompress('test', type = 'none')
[1] 74 65 73 74

So anything looking for the gzip 'magic' header will fail.

artemklevtsov commented 4 years ago

Thank you for the report. I suppose this example out of date. We should review and update it. I tested it before commit. Since then a lot of changes have been made.

mattjvincent commented 4 years ago

Just an FYI:

After installing gzmem and magrittr, I have changed your example to be:

library(RestRserve)
library(gzmem)
library(magrittr)

## ---- create handler for the HTTP requests ----

# simple response
hello_handler = function(request, response) {
  resp_body = "Hello, World!"
  enc = request$get_header("accept-encoding")
  if (!is.null(enc) && any(grepl("gzip", enc))) {
    print('encoding')
    resp_body = resp_body %>% 
                charToRaw() %>% 
                mem_compress(format = "gzip")
    response$set_header("Content-encoding", "gzip")
  }
  response$body = resp_body
  response$encode = identity # prevent convert to character
}

## ---- create application -----

app = Application$new(
  content_type = "text/plain"
)

## ---- register endpoints and corresponding R handlers ----

app$add_get(
  path = "/hello",
  FUN = hello_handler
)

## ---- start application ----
backend = BackendRserve$new()
backend$start(app, 
              http_port = 8001)

This works from browser, RCurl, httr, Python, etc.

artemklevtsov commented 4 years ago

Thank you for the investigation. I'll update the example.