0

I'm very new to web2py and to web-requests so please keep a slack hand. I try to make application with web2py framework that allow me to do following: I send POST request to remote server (server's url, for example, is https://100.100.10.100)

headers = {'Content-type': 'application/json'}
payload = {"uuid": some_file.json,
        "level": "public",
        "Url": " http://localhost:8000/myApp/default/file_to_process}
requests.post('https://100.100.10.100', data=json.dumps(payload), headers=headers)

Server receives request and with counter GET request tries to get data from some_file.json that located on my hard drive in /home/user/Desktop/some_files and linked with web2py application's page http://localhost:8000/myApp/default/file_to_process with below code

Controller:
def file_to_process():
    return dict(files=Expose('/home/user/Desktop/some_files'))
View:
{{=files}}

The problem is that server can receive only first string from file but not the whole data range... I can't understand where should I search for a mistake: in web2py code or in Python requests POST request. Please make your suggestions or provide a solution.

Anand S Kumar
  • 88,551
  • 18
  • 188
  • 176
  • Do you have control over the remote server, and if so, can you show the code it is using to retrieve the files from your desktop? – Anthony Aug 06 '15 at 14:40
  • no, I haven't, but I will try to find out that... Also I found that if to sent `cUrl` request `curl -i '//localhost:8000/myApp/default/file_to_process/some_file.json'` I got following headers info: `HTTP/1.1 200 OK Content-Type: application/json X-Powered-By: web2py Date: Fri, 07 Aug 2015 06:43:31 GMT Server: Rocket 1.2.6 Python/2.7.6 Transfer-Encoding: Chunked Connection: keep-alive` Does `Transfer-Encoding: Chunked` can cause this issue? – Alehandro Ramoz Rodrigez Aug 07 '15 at 06:55
  • @Anthony , as I just checked, it's because of `web2py` by default uses `Transfer-Encoding: Chunked` instead of `Content-Length` . So I need to set Content-length by file size. Can you please refer to new ticket http://stackoverflow.com/questions/31871772/how-to-set-response-content-length-to-infinite and answer there if you have a proper solution? thanks – Alehandro Ramoz Rodrigez Aug 07 '15 at 07:44
  • If you are using web2py's built-in development server, the file will indeed be served via chunked transfer encoding because `Expose` simply returns the file without setting the Content-Length header itself. However, if you instead use `response.stream` to server files (which is the more appropriate approach in this case), the Content-Length header will be set automatically. Details in my answer below. – Anthony Aug 07 '15 at 16:58

1 Answers1

1

The Expose functionality is really intended to enable building a UI in the browser for listing and downloading files in a given directory, and so it lacks some flexibility (e.g., it simply returns an open file object to the server without setting the Content-Length header, which can result in the file being served via chunked transfer encoding depending on how web2py is being served).

However, you really don't need Expose here, as you can simply use response.stream to serve individually requested files:

import os

def file_to_process():
    path = os.path.join('home', 'user', 'Desktop', 'some_files', *request.args)
    response.headers['Content-Type'] = 'application/json'
    return response.stream(path)

Note, if the filenames have a .json extension, setting the Content-Type header is unnecessary, as response.stream will handle that automatically.

Also, if the remote server will allow it, rather than having the remote server request the files from web2py, you might consider just posting the files directly to the remote server with the initial request (e.g., see https://toolbelt.readthedocs.org/en/latest/uploading-data.html).

Anthony
  • 25,466
  • 3
  • 28
  • 57