Can a web server store files at a host? - webserver

I'm trying to create a web server for my NodeMCU project, but I would also want it to write a JSON/TEXT file and store it at a host computer accessing the web page. Is it possible to write a JSON using HTTP requests?
Thank you!

You would use the HTTP post method to send a JSON structure to a remote host. Hence, in the NodeMCU firmware you can use the post() function of the http module like so:
http.post('http://httpbin.org/post',
'Content-Type: application/json\r\n',
'{"hello":"world"}',
function(code, data)
if (code < 0) then
print("HTTP request failed")
else
print(code, data)
end
end)

Related

Python flask: forward POST to external API

I am building a microservice for the Camunda rest API using python flask and flask_restplus, python 3.7.0. Camunda is running in a docker container, available via localhost, port 8080. All GET requests to my microservice are being forwarded to the Camunda API via redirect, which is working perfectly fine.
POST requests (tested via postman, as suggested in the official tutorial) are not being forwarded properly using
redirect(camunda_api_url)
or
request.post(camunda_api_url)
The POST request via postman is done using
Header: Content-Type: multipart/form-data
Body: upload File Object (somefile.bpmn)
When I do the POST to the Camunda REST-API directly, everything works just fine, but when I try to redirect my post via my microservice, I get status code 200, but the file isn't being uploaded.
Debugging at my endpoint I can see that the file is being received:
print(request.files['upload'])
<FileStorage: 'somefile.bpmn' ('application/octet-stream')>
Thus the file is being transmitted successfully, but the redirect doesn't work.
My endpoint method looks like this:
def post(self):
print(request.files['upload'])
test = requests.post(host_prefix + 'deployment/create', files=request.files)
print(test.status_code)
Modifying the request.post via
data=request.files
data=request.files['upload']
or omiting data completely
always results in the file not being uploaded.
Trying redirect via
redirect(host_prefix + 'deployment/create', code=307)
also results in the file not being uploaded.
How can I redirect this post request properly to the Camunda API ?
This is not a question about the Camunda API rather than how to redirect a POST request to a foreign endpoint properly.
P.S.: I created my api and endpoints like this:
app = Flask(__name__)
api = Api(app, version='0.1', title='BPMN-API', description='A BPMN-API for Camunda, implemented in python')
...
api.add_resource(CreateDeployment, api_prefix + 'deployment/create', methods=['POST'])
OK, I solved this problem by using:
requests.post(camunda_api_url, files={file_name:request.files['upload'].read()})
where camunda_api_url is the endpoint at the Camunda REST engine, file_name is the name of the file being uploaded, AND by adding a
get-method,using simply:
def get(self):
camunda_api_url = "http://localhost:8080/engine-rest/deployment/create"
return redirect(camunda_api_url)
Without the get method the post doesn't work.
-> setting topic to solved. :)
By using requests library it is very easy. The example shows multiple file uploads with same key and with other form data as well. The images are coming from a form with the key named 'images'
The example gets file list from a form with the key 'images' and forward that files to another URL or API.
images = request.files.getlist('images')
files = []
for image in images:
files.append(("images", (image.filename, image.read(), image.content_type)))
r = requests.post(url=api_urls.insert_face_data_url, data={"apikey": apikey, "faceid": faceid},
files=files)

How to upload a file using REST API Put method using JMeter

Context of my query:
Need to test REST API Put method for uploading a file
tool to be used is JMeter.
I can successfully perform the above operation using POSTMAN tool but its not working in JMeter.
Here are the JMeter Request Details;
method: PUT
Path:path
HEADER
Content-Type= multipart/form-data; boundary=----WebKitFormBoundary${random}
BODY DATA
------WebKitFormBoundary${random}
Content-Disposition: form-data; name="fileUpload"; filename="C:\temp\abc.zip"
Content-Type: application/octet-stream
------WebKitFormBoundary${random}--
RESULTS:
{"success":false,"errorMessages":"Request did not include an attachment"}
Response code = 400
Appreciate if anyone can help or provide a better way to upload a file using PUT method.
Thanks,
AB
Use MIME Type: application/zip
Your File Upload settings should look like this in JMeter:
My expectation is that you simply don't pass the file you are trying to upload along with the request. If you are building the request manually you will need to add the body of the file to your request using i.e. __FileToString() function. Check out Testing REST API File Uploads in JMeter article for more details.
Also given your request works in Postman you should be able to capture it using JMeter's HTTP(S) Test Script Recorder
Copy the file you will be uploading using Postman to the "bin" folder of your JMeter installation
Start JMeter's Proxy server. Refer JMeter Proxy Step by Step guide to learn how to do it.
Start Postman using JMeter's HTTP(S) Test Script Recorder as a proxy by passing --proxy-server option to it like:
C:\Users\your_user_name\AppData\Local\Postman\app-x.x.x\Postman.exe --proxy-server=localhost:8888
Execute your request in Postman
JMeter will store the captured request under Test Plan -> Thread Group -> Recording Controller

Cannot get response from github server

I'm using POCO library to establish communication between my app and github in order to use its API, and unfortunately after sending (successfully) very basic request I'm not getting any response:
URI uri("https://api.github.com/zen");
std::string path(uri.getPathAndQuery());
HTTPClientSession client(uri.getHost(),uri.getPort());
HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1);
client.sendRequest(req);
HTTPResponse res;
client.receiveResponse(res);//this throws error "Poco::Net::NoMessageException"
I've checked this URI and after pasting it into browser I'm getting correct response, that is, random "wisdom" from github server.
Does anyone has any idea how to fix my code so it actually gets the response?
You are trying to connect to a secure server using insecure protocol. Use HTTPSClientSession.

Using Dropbox API Drop-ins

I'm using Dropbox APIs Drop-ins, when I try to save a file I get an error message like Received non-200 response status 503 from server for url: http://www.example.com/test.txt
In my html page I use the Dropbox.save(optionsUploader); function on an input button and my js script is:
optionsUploader = {
files: [
{'url':'http://www.example.com/test.txt', 'filename':'test.txt'}
],
success: function() {},
progress: function(progress) {console.log(progress);},
cancel: function() {},
error: function(errmsg) {console.log(errmsg);}
}
Is that because I'm working on localhost ? (the www.example.com address corresponds to a 127.0.0.1)
The Dropbox Saver works by having the Dropbox servers download the file at the supplied URL. In this case, it sounds like the supplied URL is actually a localhost (127.0.0.1) URL, which won't be accessible to the Dropbox servers. (That is, you may be serving the file on your local computer, but this isn't openly available on Internet.)
The error message is telling you this, in that it's saying that the servers tried to access the file at the supplied URL but got the HTTP error code 503 ("Service Unavailable").
So, this being the case, to use the Saver, you'll need to supply a URL that's actually accessible on the Internet. This may mean hosting files on your server, or some CDN, or even a Dropbox link.

Perl SOAP::WSDL accessing HTTPS Unathorized error

I'm trying to generate a Perl library to connect to a WebService. This webservice is in an HTTPS server and my user has access to it.
I've executed wsdl2perl.pl several times, with different options, and it always fails with the message: Unauthorized at /usr/lib/perl5/site_perl/5.8.8/SOAP/WSDL/Expat/Base.pm line 73.
The thing is, when I don't give my user/pass as arguments, it doesn't even asks for them.
I've read [SOAP::WSDL::Manual::Cookbook] (http://search.cpan.org/~mkutter/SOAP-WSDL-2.00.10/lib/SOAP/WSDL/Manual/Cookbook.pod) and done what it says about HTTPS: Crypt::SSLeay is instaleld, and both SOAP::WSDL::Transport::HTTP and SOAP::Transport::HTTP are modified.
Can you give any hint about what may be going wrong?
Can you freely access the WSDL file from your web browser?
Can someone else in your network access it without any problems?
Maybe the web server hosting the WSDL file requires Basic or some other kind of Authentication...
If not necessary ,I don't recommend you to use perl as a web service client .As you know ,perl is a open-source language,although it do support soap protocol,but its support do not seem very standard.At first,its document is not very clear.And also ,its support sometimes is limited.At last,bug always exists here and there.
So ,if you have to use wsdl2perl,you can use komodo to step into the code to find out what happened.This is just what I used to do when using perl as a web service client.You know ,in the back of https is SSL,so ,if your SSL is based on certificate-authorized,you have to set up your cert path and the list of trusted server cert.You'd better use linux-based firefox to have a test.As I know ,you can set up firefox's cert path and firefox's trusted cert list.If firefox can communicated with your web service server succefully,then,it's time to debug your perl client.
To debug situations with Perl and SOAP, interpose a web proxy so you can see exactly what data is being passed and what response comes back from the server. You were getting a 401 Not authorized, I expect, but there may be more detail in the server response.
Both Fiddler http://docs.telerik.com/fiddler and Charles proxy https://www.charlesproxy.com/ can do this.
The error message you quote seems to be from this line :
die $response->message() if $response->code() ne '200';
and in HTTP world, Unauthorized is clearly error code 401, which means your website asks for a username and password (most probably, some website may "hijack" this error code to cater for other conditions like a filter on the source IP).
Do you have them?
If so, you can
after wdsl2perl has run, find in the created files where set_proxy() is called and change the URL in there to include the username and password like that : ...->set_proxy('http://USERNAME:PASSWORD#www.example.com/...')
or your in code, after instantiating the SOAP::WSDL object, call service(SERVICENAME) on it (for each service you have defined in your WSDL file), which gives you a new object, on which you call transport() to access the underlying transport object on which you can call proxy() with the URL as formatted above (yes it is proxy() here and set_proxy() above); or you call credentials() instead of proxy() and you pass 4 strings:
'HOSTNAME:PORT'
the realm, as given by the webserver but I think you can put anything
the username
the password