http post in ionic and python server - python

i use python json http server and need post json with ionic in this server,but http post method send options type.i need send post type.whats the problem?
Server:
def do_POST(self):
content_len = int(self.headers.getheader('content-length'))
post_body = self.rfile.read(content_len)
self.send_response(200)
self.end_headers()
data = json.loads(post_body)
self.wfile.write(data['id'])
return
ionic http post method:
$http.post(url, JSON.stringify({"id":"1"})).success(function (res) {
console.log("res" + res);
}).error(function (data, status, headers, config) {
console.log(data, status, headers,JSON.stringify (config));
});
Error from python server:
192.168.1.4 - - [10/Mar/2017 02:36:28] code 501, message Unsupported method ('OPTIONS')
192.168.1.4 - - [10/Mar/2017 02:36:28] "OPTIONS / HTTP/1.1" 501 -

This looks like a Cross-Origin Resource Sharing (CORS) preflight request issue.
I would recommend adding a do_OPTIONS method to your class:
def do_OPTIONS(self):
self.send_response(200, "ok")
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
self.send_header("Access-Control-Allow-Headers", "X-Requested-With")
This will tell your browser that the POST request has Access-Control.
Another good SO article on this can be found here.

Related

How to send data from localhost to server using Python requests?

I am trying to send data from localhost to an API in remote server using Python Requests & Django through an API: /api/send-data/
Path for /api/send-data/ in urls.py is path('send-data/',view_send_data.send_data,name='send_data')
This is my view_send_data.py in my localhost:
#api_view(('POST',))
#renderer_classes((TemplateHTMLRenderer, JSONRenderer))
def send_data():
# defining the API-endpoint
API_ENDPOINT = "http://68.183.89.234/api/screen/"
# data to be sent to API
data = {'data':1234}
# sending post request and saving response as response object
r = requests.post(url = API_ENDPOINT, data = data)
print(r.json())
return Response({"success": True}, status=status.HTTP_200_OK)
Path for api at http://68.183.89.234/api/screen/ in urls.py is path('screen/',views_fr.screen_display,name='screen')
This is my views_fr.py in my remote server:
#api_view(['POST'])
def screen_display(request):
if request.method == 'POST':
return Response({"success": True,
"response": request.data}, status=status.HTTP_200_OK)
When I call "http://127.0.0.1:8000/api/send-data/" in my browser, I am getting 405 Method Not Allowed
Is this the correct way to do it or am I missing something? Thank you.
The error you are getting is because the remote server API only accepts POST method, but you can't make a POST request using the browser url call. Test the API using postman or curl so you can set the correct method for request.

Python 3.6 BaseHTTPRequestHandler not responding to requests

I have a simple python server script to conditionally respond to post requests. But is not sending responses
Have searched stack overflow and online to find examples of the same behaviour
from http.server import BaseHTTPRequestHandler
import json
verb_id = "http://id.tincanapi.com/verb/rated"
print('starting')
def respond(statement):
email = statement["actor"]["mbox"]
verb = statement["verb"]["id"]
response = statement["result"]["response"]
return ('Recieved statement from {email}, verb: {verb} with response: {response}'.format(email=email, verb=verb, response=response))
class RestHTTPRequestHandler(BaseHTTPRequestHandler):
def do_POST(self):
content_len = int(self.headers.get('Content-Length'))
post_body = self.rfile.read(content_len)
parsed_body = json.loads(post_body)
verb = parsed_body["statement"]["verb"]["id"]
if (verb == verb_id):
response = respond(parsed_body["statement"])
self.wfile.write(response.encode("utf-8"))
else:
print('recieved statement without rated')
self.wfile.write("Not processed".encode("utf-8"))
self.send_response(200)
self.end_headers()
return
httpd = HTTPServer(('0.0.0.0', 8025 ), RestHTTPRequestHandler)
while True:
httpd.handle_request()
The log shows
127.0.0.1 - - [11/Apr/2019 15:56:03] "POST / HTTP/1.1" 200 -
After each request, but Postman gives me 'Could not get any response'
I would expect to be getting a 200 to all post requests and the status returned from the if statement (either the result of the respond function or "Not Processed")
I am using Python 3.6
Thanks in advance

Send raw POST request using Socket

I am trying to send a raw POST request to a chromedriver server.
Here is what I try to initiate a new session:
import socket
s = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
s.connect(("127.0.0.1", 9515))
s.send(b'POST /session HTTP/1.1\r\nContent-Type:application/json\r\n{"capabilities": {}, "desiredCapabilities": {}}\r\n\r\n')
response = s.recv(4096)
print(response)
Output:
b'HTTP/1.1 200 OK\r\nContent-Length:270\r\nContent-Type:application/json; charset=utf-8\r\nConnection:close\r\n\r\n{"sessionId":"b26166c2aac022566917db20260500bb","status":33,"value":{"message":"session not created exception: Missing or invalid capabilities\\n (Driver info: chromedriver=2.31.488763 (092de99f48a300323ecf8c2a4e2e7cab51de5ba8),platform=Linux 4.4.0-91-generic x86_64)"}}'
Summary of error: json object I am sending is not getting parsed correctly
When I use the same json object but send it by requests library, everything is OK:
import requests
params = {
'capabilities': {},
'desiredCapabilities': {}
}
headers = {'Content-type': 'application/json'}
URL = "http://127.0.0.1:9515"
r = requests.post(URL + "/session", json=params)
print("Status: " + str(r.status_code))
print("Body: " + str(r.content))
Output:
Status: 200
Body: b'{"sessionId":"e03189a25d099125a541f3044cb0ee42","status":0,"value":{"acceptSslCerts":true,"applicationCacheEnabled":false,"browserConnectionEnabled":false,"browserName":"chrome","chrome":{"chromedriverVersion":"2.31.488763 (092de99f48a300323ecf8c2a4e2e7cab51de5ba8)","userDataDir":"/tmp/.org.chromium.Chromium.LBeQkw"},"cssSelectorsEnabled":true,"databaseEnabled":false,"handlesAlerts":true,"hasTouchScreen":false,"javascriptEnabled":true,"locationContextEnabled":true,"mobileEmulationEnabled":false,"nativeEvents":true,"networkConnectionEnabled":false,"pageLoadStrategy":"normal","platform":"Linux","rotatable":false,"setWindowRect":true,"takesHeapSnapshot":true,"takesScreenshot":true,"unexpectedAlertBehaviour":"","version":"60.0.3112.90","webStorageEnabled":true}}'
Summary of output: json object is parsed successfully by the chromedriver and new session is created
Do you, guys, have an idea why sending the raw POST request using socket is not working as expected?
There are several issues about your HTTP request:
The body of the HTTP request should be separated from the head by \r\n\r\n.
You need the Content-Length field, otherwise the remote host does not know when your body is complete.
The Host field is mandatory in HTTP 1.1. (Since you receive 200 with your first request, your server probably doesn't insist.)
I've got your example to work (with an apache webserver) by using:
s.send(b'POST /session HTTP/1.1\r\nHost: 127.0.0.1:9515\r\nContent-Type: application/json\r\nContent-Length: 47\r\n\r\n{"capabilities": {}, "desiredCapabilities": {}}')
To be visually more clear, the valid HTTP request looks like
POST /session HTTP/1.1
Host: 127.0.0.1:9515
Content-Type: application/json
Content-Length: 47
{"capabilities": {}, "desiredCapabilities": {}}

Python Tornado - CORS PUT

I am facing a problem with Tornado. I have an API endpoint for PUT HTTP Method in Tornado. I also have a web application that sends the request to this API with jQuery and AJAX, but always I get a 405 response because the request is going as HTTP Method OPTIONS.
I understand the way it works and I did configured my Tornado Server to allow it. But even so I having this situation.
Can someone help me?
There is my server code:
class BaseHandler(RequestHandler):
def __init__(self, *args, **kwargs):
super(BaseHandler, self).__init__(*args, **kwargs)
self.set_header('Cache-Control', 'no-store, no-cache, must- revalidate, max-age=0')
self.set_header("Access-Control-Allow-Origin", "*")
self.set_header("Access-Control-Allow-Headers", "Content-Type")
self.set_header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS')
Many thanks
You need to add an options handler that just sends the headers with no body:
def options(self):
# no body
self.set_status(204)
self.finish()
See Tornado server: enable CORS requests for a complete code snippet.
Or else just install the tornado-cors package:
pip install tornado-cors
That will add the necessary handlers for you, and ensure the right response headers get sent.
if you don't define put method return 405
class Handler(tornado.web.RequestHandler):
def put(self):
self.set_header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
self.set_header("Access-Control-Allow-Origin", "*")
self.set_header("Access-Control-Allow-Headers", "Content-Type")
self.set_header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS')
[I 170205 04:56:35 web:1971] 200 PUT

Ionic HTTP Post successfully sends data but runs error function in app

I am trying to send an HTTP post request using AngularJS and Ionic.
The data is successfully received by my Python-based server, however the error function, rather than success, is called on the simulated device.
Here is my device code:
$http(config)
.success(function(data, status, headers, config) {
alert("Registered with MC server. Congrats!");
})
.error(function(err, data, status, headers, config) {
alert("Unable to reach MC server to register: try again another time.");
alert("Error Info : " + err + data);
});
Here is my server code:
def do_POST(self):
# Confirm receipt
# print headers
print self.headers
# Extract and print the contents of the POST
length = int(self.headers['Content-Length'])
post_data = self.rfile.read(length).decode('utf-8')
print post_data
data = json.loads(post_data)
registerUser(data['email'],data['first'],data['last'],data['uid'],data['devid'])
#SimpleHTTPServer.SimpleHTTPRequestHandler.do_POST(self)
# response to iphone app
self.send_response(200) #create header
response = "Authentication successful." #create response
self.send_header("Content-Length", str(len(response)))
self.end_headers()
self.wfile.write(response) #send response
Anyone have any ideas why this is happening?
Thank you!

Categories