I'm uploading a file using curl in one of my django project, it works fine in localhost, but when I hosted the project in remote server, it does not work.
I'm sending the file from this command
curl -i --form docfile=#/path_to_file http://example.com/process-file
and in views.py, I'm handling this file as
def process_file(request):
if request.method != 'POST':
return HttpResponseNotAllowed('Only POST Method')
docfile = request.FILES['docfile']
output = main(0, docfile) # output is json object
return HttpResponse(output,content_type = "application/json")
This works perfectly fine when i run in local machine, but sending POST request to remote server with curl returns
HTTP/1.1 100 Continue
and do nothing. File is getting uploaded. What should I do.
Thanks
Edit 1:
I tried to send some other HttpResponse (file name) from other view method, its working fine, but when i process file, it just sends HTTP/1.1 100 Continue
I don't know exactly how to fix this in your project, but it looks like your curl is sending the Expect: 100-continue header, prompting the remote server to send back HTTP/1.1 Continue. curl waits to get back that response then uploads the form. You say curl returns the HTTP/1.1 100 Continue then "does nothing," but it should actually be uploading after it receives that, so maybe whatever callback you're using isn't returning that. I would try looking at it with Wireshark.
Related
I'm sending a curl command to a HTTP Flask server I've created. The command I'm sending is as follows:
curl -X POST --data-binary #africa-toto.wav http://localhost:5000/
Is there a way to parse the actual name of the file from this command using Flask (i.e. "africa-toto.wav")? I can receive the binary data just fine, but I'm not able to find the actual filename referenced in any of the attributes of Flask's request object
I have tried checking request.files, and a few others, but no filenames seem to be getting stored anywhere
I am playing around with Python, Flask and I am trying to make an endpoint which would accept a file.
Basically I want to upload a random .txt/.json file and save it on the server for further processing.
My Problem
I followed the documentation for building it. However, there is no info there like how to build a request to post the data.
e.g use multipart/form-data and upload it with a form, or upload it in the body as binary. Anyways, I tried all possible ways in Postman, none of them works, looks like the file just doesn't reach the server. What would be the simplest solution to be able to upload it as binary in the request body? If the code looks fine what should I configure in postman to be able to upload a file??
My endpoint
class RawData(Resource):
parser = reqparse.RequestParser()
parser.add_argument('file',
type=werkzeug.datastructures.FileStorage,
required=True,
help="Required file is missing",
location='files')
def post(self):
data = RawData.parser.parse_args()
file = data['file']
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('uploaded_file',
filename=filename))
Error Message - Postman - HTTP 400
{
"message": {
"file": "Required file is missing"
}
}
Turns out to be a problem with Postman. Still didn't figure out how to post files.
However, CURL came in handy and solved the issue with the following cmd:
curl -v -X POST -H "Content-Type: multipart/form-data" -F "file=#file.txt" http://localhost:5000/api/v1/rawdata/newfile
I want to write some data, e.g. "hello" on a file that is located on a remote server, not a local server. This is the code that I used to read from server:
import urllib2
var = "hello"
url = "http://url:port/log/log.txt"
response = urllib2.urlopen(url)
txt = response.read();
print txt
As an output I was able to get the data from the log file.
Now I want to write some data, e.g. "hello" onto the same file. How to achieve that?
What your code is doing is actually not "reading a file" but sending an HTTP get request to a given url and print the HTTP response's body. What you get as content for this url is up to the HTTP server serving this url, and the fact it actually comes from a file stored on this server is totally irrelevant - it might as well come from a database, from another web server, or be typed in real time by a monkey FWIW.
If you want to use the HTTP protocol to modify the content of a given file on this server, the server must provide this service (as a given url where you're supposed to send a POST or PUT http request with the new content).
I have an API which is currently on HTTP, I moved the API using SSLify library in python flask.
Now when I send data using curl request
curl -v -k -H "Content-Type: application/json" -X POST \
--data '{"title":"foobar","body": "This body"}' \
-L http://X.Y.Z.W.us-west-2.compute.amazonaws.com/test
It returns an empty string to me by using request.data
If I make the request to begin with https it returns correct value. If there is a redirect how can I send data ?
SSLify issues a 301 or 302 redirect status code depending on your configuration. So you need to pass --post301 or --post302 to curl.
The reason for this can be found in the curl man page:
When curl follows a redirect and the request is not a plain GET (for
example POST or PUT), it will do the following request with a GET
if the HTTP response was 301, 302, or 303. If the response code was
any other 3xx code, curl will re-send the following request using
the same unmodified method.
You can tell curl to not change the non-GET request method to GET
after a 30x response by using the dedicated options for that: --post301, --post302 and -post303.
I'm tying to write some simple app on python3 and tornado for server, and requests for client, and I'm getting some headers in 'self.request.body', which I can't dispose of. For instance, for file 'blahblahblah', I get:
--cb5f6ba84bdf42d382dfd3204f6307c7\r\nContent-Disposition: form-data; name="file"; filename="1.bin"\r\n\r\nblahblahblah\n\r\n--cb5f6ba84bdf42d382dfd3204f6307c7--\r\n
Files are sent by
f = {'file': open(FILE, 'rb')}
requests.post(URL_UPLOAD, files=f)
and received by
class UploadHandler(tornado.web.RequestHandler):
def post(self, filename):
with open(Dir + filename, 'wb') as f:
f.write(self.request.body)
My full code can be seen here
When I send the file by curl with curl -X POST -d $(cat ./1.bin) http://localhost:8080/upload/1.bin I get the correct file, but without \n.
There must be something I missed. Please can someone help me with that? Thank You.
There are two ways to upload files: simply using the file as the request body (usually, but not necessarily, with the HTTP PUT method), or using a multipart wrapper (usually with the HTTP POST method). If you upload the file from an HTML form, it will usually use the multipart wrapper. Your requests example is using a multipart wrapper and the curl one is not; your server is not expecting the wrapper.
To use a multipart wrapper: in requests, pass files= as you've done here. With curl, see this answer: Using curl to upload POST data with files. On the server, use self.request.files instead of self.request.body: http://www.tornadoweb.org/en/stable/httpserver.html#tornado.httpserver.HTTPRequest.files
To not use the multipart wrapper, use data=open(FILE, 'rb').read() from requests, and keep the other two components the same.
It is possible to support both styles simultaneously on the server: use self.requests.files when self.request.headers['Content-Type'] == 'multipart/form-data' and self.request.body otherwise.