Spotify Auth + HttpPost + Gson + Client Credential Flow - spotify

I'm developing a small app to learn about request/response/gson/etc.
What i'm trying to do is: Get the token through Client Credential Flow, to get some audio features.
I followed the guide:
https://developer.spotify.com/web-api/authorization-guide/#client-credentials-flow
And worked on the same idea as the spotify api:
https://github.com/thelinmichael/spotify-web-api-java/blob/master/src/main/java/com/wrapper/spotify/SpotifyHttpManager.java
Tried diff's stuffs, but i'm stucked now.
Currently, the error is:
HttpResponseProxy{HTTP/1.1 415 Unsupported Media Type [Server: nginx, Date: Thu, 02 Mar 2017 19:59:45 GMT, Content-Length: 888, Connection: keep-alive, Keep-Alive: timeout=600] ResponseEntityProxy{[Content-Length: 888,Chunked: false]}}
Here's the actual code:
BASE64Encoder base64Encoder = new BASE64Encoder();
String encodedClientIdKey = base64Encoder.encode((clientId + ":" + clientSecretKey).getBytes());
HttpPost httpPostRequest = new HttpPost("https://accounts.spotify.com/api/token");
httpPostRequest.setHeader("Content-Type", "application/json");
httpPostRequest.addHeader("Authorization", "Basic " + encodedClientIdKey);
JsonObject json = new JsonObject();
json.addProperty("grant_type", "client_credentials");
StringEntity stringEntity = new StringEntity(json.toString(), ContentType.APPLICATION_JSON);
httpPostRequest.setEntity(stringEntity);
HttpResponse post = httpClient.execute(httpPostRequest);
I thought it was a content type problem, but couldn't solve by setting it on header or entity.
Any ideas?
PS:
Tried using form urlencoded instead of json as content type, here's the code (tried add content on header then as parameter as well):
BASE64Encoder base64Encoder = new BASE64Encoder();
String encodedClientIdKey = base64Encoder.encode((clientId + ":" + clientSecretKey).getBytes());
HttpPost httpPostRequest = new HttpPost("https://accounts.spotify.com/api/token");
httpPostRequest.setHeader("Content-Type", "application/x-www-form-urlencoded");
httpPostRequest.addHeader("Authorization", "Basic " + encodedClientIdKey);
List<NameValuePair> nameValuePairs = new ArrayList<>();
nameValuePairs.add(new BasicNameValuePair("grant_type", "client_credentials"));
nameValuePairs.add(new BasicNameValuePair("Content-Type", "application/x-www-form-urlencoded"));
httpPostRequest.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse post = httpClient.execute(httpPostRequest);
System.out.println(post);
And the error was Bad request this time:
HttpResponseProxy{HTTP/1.1 400 Bad Request [Server: nginx, Date: Thu, 02 Mar 2017 20:14:50 GMT, Content-Type: application/json, Content-Length: 70, Connection: keep-alive, Keep-Alive: timeout=600] ResponseEntityProxy{[Content-Type: application/json,Content-Length: 70,Chunked: false]}}

Related

How to automate downloading attachment from Rest API GET response in SoapUI

I am using SoapUI 5.5.0 and I am trying to automate the download of an .xls attachment from a Rest API GET response.
It does not appear in the attachment tab of the response.
I tried adding "Enable MTOM | true" but the request stop working with
it.
I tried some groovy scripts but I didn't get anything out of what I tried.
**RAW RESPONSE**
HTTP/1.1 201
Set-Cookie: Design_Authorization=VeryLongToken; Max-Age=93600; Expires=Tue, 12-Jan-2021 22:33:22 GMT; Path=/Redacted; HttpOnly
Set-Cookie: JSESSIONID=bunchofnumbers; Path=/Redacted; HttpOnly
Content-Disposition: attachment; filename=SoapUI_Export_DD_20210111_153209.xls
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/vnd.ms-excel
Transfer-Encoding: chunked
After this, the response has a bunch of unreadable characters.
If I look at the XML tab I get this:
**XML RESPONSE**
<data contentType="application/vnd.ms-excel" contentLength="647680">0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAAOwADAP7/CQAGAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAAEAAA/v///wAAAAD+////AAAAAAEAAACAAAAAAAEAAIABAAAAAgAAgAIAAAADAACAAwAAAAQAAIAEAAD///...it's very long
Adding this here since I could not get a readable format in my thank you comment below.
I had a null error on the response.getProperty('Content-Disposition').split('=')[1] line.
Since I generate and store the name of the export earlier in the testcase, I get the property and then use it.
This is what I ended with:
import org.apache.commons.io.FileUtils
def testStep = testRunner.testCase.testSteps['test step name']
def response = testStep.testRequest.response
assert response.getContentType() == 'application/vnd.ms-excel'
def data = response.getRawResponseBody()
// define filepath/name
exportname = testRunner.testCase.getPropertyValue("exportName")
reportfolder = (System.getProperty("user.home") + File.separatorChar + "Documents" + File.separatorChar);
def filename = reportfolder + exportname +'.xls'
def file = new File(filename)
FileUtils.writeByteArrayToFile(file, data) `
The body of the response is the file. You have to extract it, something like this:
import org.apache.commons.io.FileUtils
def testStep = testRunner.testCase.testSteps['test step name']
def response = testStep.testRequest.response
assert response.getContentType() == 'application/vnd.ms-excel'
def data = response.getRawResponseBody()
// define some filename
def filename = response.getProperty('Content-Disposition').split('=')[1]
def file = new File(filename)
FileUtils.writeByteArrayToFile(file, data)

retrofit2 with 2 multiparts - JSON and File is failed

I'm trying to call an external ReST service.
retrofit_version = "2.9.0"
okhttp = "3.14.9"
This is the Retrofit interface as I define it:
#Multipart
#POST("orgs/{orgUuid}/patients/{patientId}/documents")
Call<DocUploadRes> uploadDocForPatient(#Header("Authorization") String authorization,
#Path("orgUuid") String orgUuid,
#Path("patientId") Integer patientId,
#Part("metadata") RequestBody metadata,
#Part MultipartBody.Part file);
My Client call is as follow:
RequestBody metadataBody = RequestBody.create(MediaType.parse("application/json"), content);
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file","Safereport", RequestBody.create(MediaType.parse("application/pdf"), file.getBytes()));
Response<DocUploadRes> response = pccPatientRestApi.uploadDocForPatient(getBearerAuthHeader(pccAccessToken), pccOrgUuid, patientId, jsonPart, filePart).execute();
When I'm running this code with retrofit I'm getting Bad Request from the server with:
status":"400","title":"Bad Request.","detail":"File type is not supported"
But when I run the same service from postman it working successfully with the following http request sent:
POST /api/public/preview1/orgs/E58A8604-38F2-4098-879E-C6BCC6D01EB8/patients/372842/documents HTTP/1.1
Host: connect2.pointclickcare.com
Authorization: Bearer iy8OUOVa46oxaYRMVYlRApqDW00m:2Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="/C:/Users/user/Desktop/RosieConnect-20-API-User-Manual-Ver-07172018.pdf"
Content-Type: application/pdf
(data)
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="metadata"
{"documentCategory":1,"documentName":"Safebeing Report","effectiveDate":"2020-05-26T08:03:49.895Z"}
----WebKitFormBoundary7MA4YWxkTrZu0gW
It seems to me that retrofit doesn't send the 'application/pdf' in the Content-Type header of the file #Part... how can it be fixed?
Any idea will be very much appreciated!
-- Update ---
It appears the the file extension is mandatory.
Problem solved by adding .pdf to the file name
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file","report.pdf", RequestBody.create(MediaType.parse("application/pdf"), file.getBytes()));

Simple Http Server Issue on Micropython (ESP8266)

I am sending same post to Simple Http Server(Micropython) installed on ESP8266 and BaseHTTPServer(Python) on PC from my mobile APP (iOS-Swift 4).
On PC, i am getting Payload successfully as seen below, However, when i post to ESP8266, i am not seeing any payload in the body and after 3-5 request, i am getting an following error; you can see the code in ESP8266 and request method in Swift below; (if i remove JSON data from my request in Swift, i am not getting following error, only header is successfully posted to ESP8266)
ERROR in SWIFT after 3-5 Post Request;
2018-02-06 15:58:48.381801+0300 Chroma[1655:40174] TIC TCP Conn Failed [49:0x60400016c6c0]: 1:61 Err(61)
2018-02-06 15:58:48.385161+0300 Chroma[1655:40174] Task <542713C7-815D-479B-A462-DBD6A6EBB795>.<49> HTTP load failed (error code: -1004 [1:61])
2018-02-06 15:58:48.386808+0300 Chroma[1655:40159] Task <542713C7-815D-479B-A462-DBD6A6EBB795>.<49> finished with error - code: -1004
Could not connect to the server.
PC-DEBUG (SUCCEED);
----- Request Start ----->
Request path: /
Content Length: 20
Request headers: Host: 0.0.0.0:10000
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Accept: application/json
User-Agent: Chroma
Accept-Language:
Content-Length: 20
Accept-Encoding: gzip, deflate
Request payload: {"COLOR":[0,255,95]}
<----- Request End -----
ESP8266-DEBUG(PAYLOAD NOT SEEN) ;
POST / HTTP/1.1
Host: 192.168.1.171:8080
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Accept: application/json
User-Agent: Chroma
Accept-Language:
Content-Length: 20
Accept-Encoding: gzip, deflate
CODE ON ESP8266
def webServer():
s = socket.socket()
ai = socket.getaddrinfo("192.168.1.171", 8080)
print("Bind address info:", ai)
addr = ai[0][-1]
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(addr)
s.listen(2)
while True:
res = s.accept()
client_sock = res[0]
client_addr = res[1]
# print("Client address:", client_addr)
# print("Client socket:", client_sock)
req = client_sock.recv(1024)
print("Request: %s" % req.decode())
client_sock.send("HTTP/1.0 200 OK\r\n\r\n'Color: JSON'\r\n")
client_sock.close()
print()
SWIFT REQUEST CODE
func sendPostToServer(color: [Int]) {
var json = [String(): [Int()]]
json = ["COLOR": color]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
// create post request
let url = URL(string: "http://192.168.1.171:8080")!
// let url = URL(string: "http://0.0.0.0:10000")! //to pc server
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("", forHTTPHeaderField: "Accept-Language")
request.setValue("Chroma", forHTTPHeaderField: "User-Agent")
// insert json data to the request
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
return
}
let dataString = String(data: data, encoding: .utf8) ?? ""
print("Response \(dataString)")
}
task.resume()
}

nodejs http post request instagram follow/unfollow

I have a script that uses cookies to make instagram post requests.
Problem: My follow requests dont work but my unfollow does
Works (statuscode = 200)
var url = 'https://www.instagram.com/web/friendships/19237590/unfollow/';
Doesnt Work (statuscode = 302)
var url = 'https://www.instagram.com/web/friendships/19237590/follow/';
So a status code of 302 is a redirect, it should provide another URL in a location header. e.g.
HTTP/1.1 302 FOUND
Connection: keep-alive
Server: meinheld/0.6.1
Date: Sat, 27 Jan 2018 10:51:09 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 0
Location: http://example.com
You can then follow this..
If you want to try this out on another URl try:
https://httpbin.org/redirect-to?url=http%3A%2F%2Fexample.com%2F

Stripping quotes from response and transferring to request endpoint

I'm using SoapUI for testing some REST api. As a response I'm getting the URL that should be an endpoint of the next request.
I made the following Property Transfer step
source : myApiCall
property : response
target : myHttpCall
property : endpoint
Everything would be ok, but when transferred the endpoint looks like "www.myurl.com" (with quotes) and thus is invalid. How do I strip the quotes from there?
Raw response :
HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 98
Content-Type: application/json; charset=utf-8
Expires: Tue, 25 Oct 2016 09:04:28 GMT
Server: Microsoft-IIS/8.5
X-Powered-By: ASP.NET
Date: Tue, 25 Oct 2016 09:04:28 GMT
"http://myurl.com/query?queryUid=90e97bdb-00a3-47c2-8809-c15ceec6ea1b"
The problem is that your Raw response include the " quotes in the String. Then you've two possible solutions, remove the " from the Raw response and keep using the same property transfer.
Or if you can not change the response then you can use a Groovy script testStep to get the Raw response and manipulated it to remove the additional " quotes before set the endpoint:
// get your api call
def myApiCall = context.testCase.getTestStepByName('myApiCall')
// get the raw response
def responseUrl = myApiCall.getPropertyValue('Response')
// since your response contains the `"` remove it
responseUrl = responseUrl.replace('"','')
// set the endpoint correctly
def httpCall = context.testCase.getTestStepByName('myHttpCall')
httpCall.setPropertyValue("endpoint",responseUrl)

Resources