415 error when sending data to a server - json

I am building an app using ionic/cordova that will take a scan, store this to the device (this part works), and also upload this data to a server (this part doesn't work).
The server is a RESTful api that expects JSON to be POSTed (I didn't create the server, these are the details I have been given).
When I try to post to the server I am getting the following error -
{status: 415, url: "http://jsfitnessservice.azurewebsites.net/api/values123", headers: {…}, error: ""} error:""
headers:
content-length:"0"
date:"Tue, 06 Feb 2018 19:41:36 GMT"
request-context:"appId=cid-v1:bf5436d9-7e1e-491e-b79d-d40d9b401307"
server:"Kestrel"
x-android-received-millis:"1517946100312"
x-android-response-source:"NETWORK 415"
x-android-selected-protocol:"http/1.1"
x-android-sent-millis:"1517946100070"
x-powered-by:"ASP.NET"
My code -
let httpData = {
"id": this.device.uuid,
"scanDateTimes": this.lastScans,
"appVersion": "Version 1.0"
}
let header = new Headers();
header.append('Content-Type', 'application/json; charset=utf-8');
this.http.post('http://jsfitnessservice.azurewebsites.net/api/values 123', httpData, header).then
(data =>{
console.log("Data Status - ", data.status);
}).catch(error =>{
console.log("Error - ", error)
});
I have tried a few things that I have seen online, such as adding the header to an object, or using JSON.Stringify() around the data I am sending. But these give errors too.
JSON.stringify around data gives this error -
status: -1, error: "unsupported params type, needs to be a JSON object"
Making header an object gives this error -
status: 0, error: "advanced-http: header values must be strings", headers: {…}}

Have you tried using
this.http.setDataSerializer(‘json’)
this.http.post('http://jsfitnessservice.azurewebsites.net/api/values 123', httpData, {'Content-Type': 'application/json; charset=utf-8'}).then
(data =>{
console.log("Data Status - ", data.status);
}).catch(error =>{
console.log("Error - ", error)
});

Related

HTTP Post Python

please help to resolve the issue, I sent payload, but get error 400:
Post:
payload = {"country_code":"XX","phone_number":"1234567890"}
r = requests.post("https://site.su/jwt-auth/start", params=payload, headers=headers, verify=False)
r.json()
{'statusCode': 400,
'reason': 'invalid_request',
'errorId': 'c2114dc8-0632-49c6-8cfb-cc5b08897ecc',
'message': 'Validation failed: \n -- PhoneNumber: phone_number is reuiqred Severity: Error',
'localizedMessage': 'One of parameter was sent with an error. Please try again or go back to the previous page.',
'invalidParameters': {'phone_number': {'reason': 'NotEmptyValidator',
'localizedMessage': 'phone_number is required'}}}
Content-Disposition: form-data; name="cd[formFeatures]"
[{"id":"","name":"country_code","tag":"input","inputType":"text"},{"id":"","name":"","tag":"input","inputType":"text","valueMeaning":"empty"},{"id":"","name":"phone_number","tag":"input","placeholder":"+7 (___) ___-__-__","inputType":"tel"}]
Payload
I have provided my code.

500 Internal Server Error from third party API

Python 3.6 - Scrapy 1.5
I'm scraping the John Deere warranty webpage to watch all new PMP's and its expiration date. Looking inside network communication between browser and webpage I found a REST API that feed data in webpage.
Now, I'm trying to get json data from API rather scraping the javascript page's content. However, I'm getting a Internal Server Error and I don't know why.
I'm using scrapy to log in and catch data.
import scrapy
class PmpSpider(scrapy.Spider):
name = 'pmp'
start_urls = ['https://jdwarrantysystem.deere.com/portal/']
def parse(self, response):
self.log('***Form Request***')
login ={
'USERNAME':*******,
'PASSWORD':*******
}
yield scrapy.FormRequest.from_response(
response,
url = 'https://registration.deere.com/servlet/com.deere.u90950.registrationlogin.view.servlets.SignInServlet',
method = 'POST', formdata = login, callback = self.parse_pmp
)
self.log('***PARSE LOGIN***')
def parse_pmp(self, response):
self.log('***PARSE PMP***')
cookies = response.headers.getlist('Set-Cookie')
for cookie in cookies:
cookie = cookie.decode('utf-8')
self.log(cookie)
cook = cookie.split(';')[0].split('=')[1]
path = cookie.split(';')[1].split('=')[1]
domain = cookie.split(';')[2].split('=')[1]
yield scrapy.Request(
url = 'https://jdwarrantysystem.deere.com/api/pip-products/collection',
method = 'POST',
cookies = {
'SESSION':cook,
'path':path,
'domain':domain
},
headers = {
"Accept":"application/json",
"accounts":["201445","201264","201167","201342","201341","201221"],
"excludedPin":"",
"export":"",
"language":"",
"metric":"Y",
"pipFilter":"OPEN",
"pipType":["MALF","SAFT"]
},
meta = {'dont_redirect': True},
callback = self.parse_pmp_list
)
def parse_pmp_list(self, response):
self.log('***LISTA PMP***')
self.log(response.body)
Why am I getting an error? How to get data from this API?
2018-07-05 17:26:19 [scrapy.downloadermiddlewares.retry] DEBUG: Retrying <POST https://jdwarrantysystem.deere.com/api/pip-products/collection> (failed 1 times): 500 Internal Server Error
2018-07-05 17:26:20 [scrapy.downloadermiddlewares.retry] DEBUG: Retrying <POST https://jdwarrantysystem.deere.com/api/pip-products/collection> (failed 2 times): 500 Internal Server Error
2018-07-05 17:26:21 [scrapy.downloadermiddlewares.retry] DEBUG: Gave up retrying <POST https://jdwarrantysystem.deere.com/api/pip-products/collection> (failed 3 times): 500 Internal Server Error
2018-07-05 17:26:21 [scrapy.core.engine] DEBUG: Crawled (500) <POST https://jdwarrantysystem.deere.com/api/pip-products/collection> (referer: https://jdwarrantysystem.deere.com/portal/)
2018-07-05 17:26:21 [scrapy.spidermiddlewares.httperror] INFO: Ignoring response <500 https://jdwarrantysystem.deere.com/api/pip-products/collection>: HTTP status code is not handled or not allowed
I found the problem: This is a POST request that must have a body data in json format, because unlike a GET request, the parameters don't go in the URI. The request header need too a "content-type": "application/json". See: How parameters are sent in POST request and Rest POST in python. So, editing the function parse_pmp:
def parse_pmp(self, response):
self.log('***PARSE PMP***')
cookies = response.headers.getlist('Set-Cookie')
for cookie in cookies:
cookie = cookie.decode('utf-8')
self.log(cookie)
cook = cookie.split(';')[0].split('=')[1]
path = cookie.split(';')[1].split('=')[1]
domain = cookie.split(';')[2].split('=')[1]
data = json.dumps({"accounts":["201445","201264","201167","201342","201341","201221"],"excludedPin":"","export":"","language":"","metric":"Y","pipFilter":"OPEN","pipType":["MALF","SAFT"]}) # <----
yield scrapy.Request(
url = 'https://jdwarrantysystem.deere.com/api/pip-products/collection',
method = 'POST',
cookies = {
'SESSION':cook,
'path':path,
'domain':domain
},
headers = {
"Accept":"application/json",
"content-type": "application/json" # <----
},
body = data, # <----
meta = {'dont_redirect': True},
callback = self.parse_pmp_list
)
Everything works fine!

Requests module JSONDecodeError

I have the following code to post using requests module
api_path = r'/DeviceCategory/create'
api_server = (self.base_url + api_path)
logging.info("Triggered API : %s", api_server)
arguments = {"name": "WrongTurn", "vendor": "Cupola", "protocolType": "LWM2M"}
headers = {'content-type': 'application/json;charset=utf-8', 'Accept': '*'}
test_response = requests.post(api_server,headers=headers,cookies=self.jessionid,
timeout=30, json=arguments)
logging.info(test_response.headers)
logging.info(test_response.request)
logging.info(test_response.json())
logging.info(test_response.url)
logging.info(test_response.reason)
The following response i got in header
2017-08-22 12:03:12,811 - INFO - {'Server': 'Apache-Coyote/1.1', 'X-FRAME-OPTIONS': 'SAMEORIGIN, SAMEORIGIN', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, DELETE, PUT', 'Access-Control-Allow-Headers': 'Content-Type', 'Content-Type': 'text/html;charset=utf-8', 'Content-Language': 'en', 'Transfer-Encoding': 'chunked', 'Content-Encoding': 'gzip', 'Vary': 'Accept-Encoding', 'Date': 'Tue, 22 Aug 2017 06:33:12 GMT', 'Connection': 'close'}
And JSON decoding the error
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Can some please help me out, the status code i got is 500
It means that the server didn't return any response values (there was no response body, so json() couldn't decode the JSON). Given the 500 error, that probably means that your API call was bad. Not being familiar with the API, I cannot say more but my guess is that you are passing the arguments wrong, try something like:
test_response = requests.post(api_server,headers=headers,cookies=self.jessionid,
timeout=30, data=arguments)

Parsing html/text return type to be able to see the content with AFNetworking

I am constrained to using AFNetworking, but I am working in Swift. I am trying to retrieve data from a POST API request that is supposed to be returning JSON. However it seems that no matter how I make the request I am not able to see what is being returned and that it does not seem to be in proper JSON format. Here's what I've tried.
(1) The canonical approach:
manager.responseSerializer = AFJSONResponseSerializer.init(readingOptions: .AllowFragments)
manager.responseSerializer.acceptableContentTypes = serialiazationTypes
This produces the error: Invalid value around character 2
Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 2." UserInfo={NSDebugDescription=Invalid value around character 2., NSUnderlyingError=0x60800004ad70 {Error Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: bad request (400)" UserInfo={com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x608000a2c140> { URL: https://API_ADDRESS} { status code: 400, headers {
Connection = "keep-alive";
"Content-Length" = 2261;
"Content-Type" = "text/html; charset=utf-8";
Date = "Wed, 07 Dec 2016 15:46:26 GMT";
Server = "nginx/1.10.1";
} },
(2) Using the standard parser. So basically I removed any explicit setting of the response serializer, which produced this error:
Optional(Error Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: bad request (400)" UserInfo={NSUnderlyingError=0x60000004ace0 {Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/html" UserInfo={com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x61800082e6a0> { URL: https://API_ADDRESS } { status code: 400, headers {
Connection = "keep-alive";
"Content-Length" = 2261;
"Content-Type" = "text/html; charset=utf-8";
Date = "Wed, 07 Dec 2016 15:49:12 GMT";
Server = "nginx/1.10.1";
(3) So then I tried to read as text/html, not requiring JSON, so that I could see what the problem is, but I don't seem to be able to retrieve this and just see what the content is either. So with this code:
manager.responseSerializer = AFHTTPResponseSerializer()
I ended up with this response, which does not even indicate why this is a bad request:
"Request failed: bad request (400)"
{ status code: 400, headers {
Connection = "keep-alive";
"Content-Length" = 2261;
"Content-Type" = "text/html; charset=utf-8";
Date = "Wed, 07 Dec 2016 15:51:10 GMT";
Server = "nginx/1.10.1";
} }
Here are my questions
(1) In cases 1 & 2 above are these problems with parsing the response code whereas in case 3 I am just seeing the server tell me that my request is bad?
(2) How can I start figuring out why my request is bad? This is an internal API, but I'm not getting a lot of help with how it works. I have a sample curl command that does work with the API, but I'm not clear on how I am departing from it:
curl -X POST -v -s -H "Session-Token: EYYW$YW$YWYW" -H "Content-type: application/json" -d#sample.json https://API_ADDRESS
What is different between that and what I am doing below:
manager.requestSerializer = AFJSONRequestSerializer()
manager.responseSerializer = AFHTTPResponseSerializer()
manager.requestSerializer.setValue(sessionToken, forHTTPHeaderField: tokenString)
manager.requestSerializer.setValue("application/json", forHTTPHeaderField: "Content-type")
manager.POST(
user_url,
parameters: nil,
success: { (operation: AFHTTPRequestOperation?,
responseObject: AnyObject!) in
print("JSON FROM POST: \(responseObject)")
},
failure: { (operation: AFHTTPRequestOperation?, error: NSError?) in
print("there was an error in POST: \(error)")
}
)

Issue Xcode change char "#" to "%40"

I've use the AFNetworking in my app.
When I'll use the AFN with field EMAIL appear this error:
Error: Error Domain=AFNetworkingErrorDomain Code=-1011 "Request failed: not found (404)" UserInfo=0x1096634a0 {NSLocalizedDescription=Request failed: not found (404), NSErrorFailingURLKey=http://mywebservice/vlemail?email=me%40domain.com, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0x109558d10> { URL: http://mywebservice/vlemail?email=me%40domain.com } { status code: 404, headers {
Connection = "keep-alive";
"Content-Length" = 967;
"Content-Type" = "text/html;charset=utf-8";
Date = "Mon, 28 Apr 2014 19:01:43 GMT";
Server = "nginx admin";
} }, NSUnderlyingError=0x1096756e0 "Request failed: unacceptable content-type: text/html"}
It's weird, because the field EMAIL is:
NSLog(#" txtEmail.: %#",_txtEmail.text) = [2908:60b] txtEmail.: me#domain
But in the params of the AFN is changed to: me%40domain
Somebody knows why?
Thanks a lot!
That's probably because the # sign is encoded as %40, similarly to how a space is encoded as %20.
http://en.wikipedia.org/wiki/Percent-encoding