How can I prevent RestSharp from double escaping a string containing end quotes? - encoding

I'm using RestSharp to consume a PHP based rest API (magento). I'm running into an issue where my request.Content contains a string escaped with backslashes. Like this: "\"mystringIsEscaped\"". It should just be a normal string "mystringIsNotEscaped".
The API does not give double quotes any specific treatment. A JSON response looks like this:
{
"value": 1
}
OR
"SomeValueAsJustString"
Here is my code so far:
// PART 1: Getting an Unauthorized Request Token
var request = new RestRequest("/rest/V1/integration/admin/token", Method.POST);
request.AddJsonBody(new {username = "this.adminUserName", password = "this.adminPassword"});
request.AddHeader("content-type", "application/json");
var _client = new RestClient(_url);
var _jsonSerializer = new JsonSerializer();
_client.AddDefaultHeader(_contentTypeHeaderWithUnderscore ? "Content_Type" : "Content-Type", "application/json");
_client.ClearHandlers(); // http://stackoverflow.com/questions/22229393/why-is-restsharp-addheaderaccept-application-json-to-a-list-of-item
_client.AddHandler("application/json", _jsonSerializer);
var response = _client.Execute(request);
response.Content is double escaped.
My raw response (using fiddler) looks like this:
HTTP/1.1 200 OK
Server: nginx/1.17.1
Date: Mon, 22 Jul 2019 12:38:44 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Set-Cookie: PHPSESSID=873l8qhalaltets0tpa2s2sta1; expires=Mon, 22-Jul-2019 13:38:44 GMT; Max-Age=3600; path=/; domain=dev.myurlthatimhiding.org; HttpOnly
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
X-Frame-Options: SAMEORIGIN
Vary: Accept-Encoding
Content-Length: 34
"mysecuretokenstringthatimnotshowing"
How do I get RestSharp to not double encode, or more specifically, to properly handle the double quotes returned?

The response is generated on the PHP side. And as you can see with fiddler, the double quotes are coming from the PHP side and are not inserted by RestSharp.
The content type is the response generated by the PHP service is:
Content-Type: application/json; charset=utf-8
So it's supposed to be JSON.
Usually, JSON data is longer and structured. But it's also valid to return just a string. And in JSON, a string must be enclosed in double quotes.
The back slashes are an artifact of the debugger. I assume you are using Visual Studio. It displays all strings the way the would appear in your source code. In source code you would write:
var t = "\"mysecuretokenstringthatimnotshowing\"";
So the back slashes aren't contained, neither in the response nor in the string. It's just the debugger display.
It's a strange use of JSON. But it's valid. Just remove the double quotes at the beginning and at the end of the string and your fine.

Looks like Execute() gives you content as a string, which would be with the double quotes. To deserialize, you need to provide a type:
var response = request.Execute<string>();
var token = response.Content;
link

Related

Signing issue when sending payload to Swish API

I am trying to send a payload to Swish (Swedish payment system), using TLS- and signing certificates. I am currently working with the Merchant Swish Simulator and using test-certificates from Swish documentation.
When sending the payload and signature (to endpont /api/v1/payouts) I get this error:
{StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
{
Date: Tue, 12 Apr 2022 07:02:19 GMT
Server: openresty/1.15.8.3
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Transfer-Encoding: chunked
Content-Type: application/json
}}
The code below is used to generate the signature
var payloadJson = JsonConvert.SerializeObject(payload, Formatting.None, serializerSettings);
var payloadJsonBuffer = Encoding.UTF8.GetBytes(payloadJson);
using var sha512 = SHA512.Create();
var hashedBuffer = sha512.ComputeHash(payloadJsonBuffer);
using var rsa = signCert.GetRSAPrivateKey();
var signedBuffer = rsa.SignHash(hashedBuffer, HashAlgorithmName.SHA512, RSASignaturePadding.Pkcs1);
var signature = Convert.ToBase64String(signedBuffer, Base64FormattingOptions.None);
var requestBody = new SwishPayoutRequestBody
{
Payload = payload,
Signature = signature
};
Does anyone have an idea to how to approach this issue or have any experience with working with Swish API using c#?
Thanks!

can't get web page source from url in Swift

I'm currently using SwiftHTTP for getting source of url address. I am using 'get method' for getting source code of url address which is
do {
let opt = try HTTP.GET(self.my_url_address!)
opt.start { response in
if let err = response.error {
print("error: \(err.localizedDescription)")
return
}
print(response.description)
}
} catch let error {
print("got an error creating the request: \(error)")
}
after this code run I got this output in Xcode output screen
URL: http://myweburl.com/detay/swat-under-siege.html
Status Code: 200
Headers: Content-Type: text/html
Connection: keep-alive
CF-RAY: 38391215a60e2726-FRA
Set-Cookie: ASPSESSIONIDSABBBSDT=HPKKPJGCDLKMDMILNGHPCAGD; path=/
Date: Mon, 24 Jul 2017 18:51:24 GMT
Vary: Accept-Encoding
X-Powered-By: ASP.NET Transfer-Encoding: Identity
Server: cloudflare-nginx
Content-Encoding: gzip
Cache-Control: private
The status code is 200 but the output is not the source code of url. How can I fix this?
Response is correct. I've tried requesting the website (the real one) and it works:
print(response.data.base64EncodedString())
If you decode the BASE64 data, it will render valid HTML code.
The issue seems related to encoding. After checking the website's head tag, it states that the charset is windows-1254
String(data: response.data, encoding: .windowsCP1254) // works. latin1, etc.
Your issue is similar to SWIFT: NSURLSession convert data to String

Angular2 Http Response missing header key/values

I'm making an http.patch call to a REST API that is successful (Status 200) but not all the response headers key/values are being returned. I'm interested in the ETag key/value.
Here is a code snippet:
let etag:number = 0;
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('If-Match', String(etag));
this.http.patch(
'http://example.com:9002/api/myresource/',
JSON.stringify(dto),
{headers: headers}
)
.subscribe(
(response:Response) => {
let headers:Headers = response.headers;
let etag:String = headers.get('ETag');
console.log(etag);
}
);
When making the same call with a REST Client (Postman), the response header contains:
Content-Type: application/hal+json;charset=UTF-8
Date: Mon, 01 Feb 2016 05:21:09 GMT
ETag: "1"
Last-Modified: Mon, 01 Feb 2016 05:15:32 GMT
Server: Apache-Coyote/1.1
Transfer-Encoding: chunked
X-Application-Context: application:dev:9002
Is the missing response header key/values a bug?
Can the issue be resolved with configuration?
This isn't an Angular issue, rather a CORS one. By definition, CORS will only return six "simple" headers: Cache-Control, Content-Language, Content-Type, Expires, Last-Modified and Pragma.
That's why you see the full set when using a REST client such as Postman, yet when calling from your Angular client, you'll only see the set limited by CORS.
To solve this, you'll need to add an Access-Control-Expose-Headers header along the following lines:
let headers = new Headers();
headers.append('Access-Control-Expose-Headers', 'etag');
let options = new RequestOptions({ headers: headers });
return this.http.get(uri, options).map(this.extractData).catch(this.catchError);
Note that you may need to augment the server side code to support the required exposed headers.
In my case (C#), I revised the EnableCors call (within WebApiConfig) to include "ETAG" in the list of exposed headers (the fourth parameter of the EnableCorsAttribute function).

SOAP UI - Split HTTP Response Header and transfer to property

I am obtaining the following response to a HTTP Request in SOAP UI
TTP/1.1 201 Created
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
Location: /api/authorization_servers/5362c2c46362f0e7f33379e8
Content-Type: application/json
Transfer-Encoding: chunked
I would like to get the value of 5362c2c46362f0e7f33379e8 in the Location Response Header and transfer it to a Project property called "token". Can someone tell me how I am going to do that?
I am able to get the entire /api/authorization_servers/5362c2c46362f0e7f33379e8 into a variable through Groovy script in this way:
def headerValue = testRunner.testCase.getTestStepByName("Register Authorization Server").httpRequest.response.responseHeaders["Location"]
I am not able to proceed any further. Any help is greatly appreciated!
You have several options if I understand you right.
You could split the value and take the last element:
headerValue = headerValue.split( '/' )[ -1 ]
You could subtract the beginning of the header:
headerValue = headerValue - '/api/authorization_servers/'
Or you could use a regular expression:
headerValue = headerValue.find ~/[a-f0-9]+$/

Having Get single and Get all methods on a ApiController

I'm developing an API using close to the latest bits from the aspnetwebstack Codeplex project (4592e2f63c55 from 2012-05-09 if anyone is interested).
I have the following route:
context.Routes.MapHttpRoute("SiteSpecific", "Api/{controller}/{customerId}/{siteToken}/{id}",
new { id = UrlParameter.Optional });
And what I'm currently trying to do is implement get single and a get all in an ApiController. The Get all method, for testing is the following:
public IEnumerable<EditChatResponse> Get(string customerId, string siteToken)
{
return new []{new EditChatResponse{Template = "Get All"}, };
}
And the get single is currently following:
public EditChatResponse Get(string customerId, string siteToken, string id)
{
return new EditChatResponse {Template = "Get Single"};
}
However, routing is always choosing the Get single method:
$ curl -i -H "Accept: applicaiton/json" http://localhost/api/chatresponse/a/b
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 14 May 2012 18:06:26 GMT
Content-Length: 66
{"Id":0,"Template":"Get Single","Inherited":false,"Enabled":false}
$ curl -i -H "Accept: applicaiton/json" http://localhost/api/chatresponse/a/b/c
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 14 May 2012 18:06:28 GMT
Content-Length: 66
{"Id":0,"Template":"Get Single","Inherited":false,"Enabled":false}
I've tried renaming the Get all method to GetAll, as I've seen in some examples, decorating it with [HttpGet], but it still chooses the single method.
Am I completely missing something, or do I need to go about this a different way (most of the examples I see look to be related to the beta bits, and not a recent version from CodePlex)?
Try using this for the default id parameter:
new { id = System.Web.Http.RouteParameter.Optional }