cherrypy page handler returning a combo response with both string and bytes object - cherrypy

I'm using Cherrypy to build my web application server. In one page handler my response body is in this format:
{
"fileId": "=+afeincas340t5u3tg9",
"fileBody": ...(some bytes here)
}
I cannot use json.dumps as the bytes part is not json serializable. How can I return this in my page handler and return it to the frontend?

You can serialize the binary content of the file with base64.
import base64
response = json.dumps({
"fileId": "=+afeincas340t5u3tg9",
"fileBody": base64.standard_b64encode(b"some bytes").decode()
})
In the client side (js) you can obtain the original bytes with the atob function.

Related

TypeError: Converting circular structure to JSON when axios response is forwarded

I have an API where I need to call another API inside the controller function. Which I do using Axios, but when I try to attach Axios's response on my original API's response, it throws this error:
TypeError: Converting circular structure to JSON.
Here's a sample code snippet
const userController = async (req,res)=>{
const ax = await axios.put(someURL, reqBody)
res.status(200).json(ax)
}
I know it's nonsensical to do something like this and I know why this error is caused but could somebody explain to me How it's happening in this case?
TypeError: Converting circular structure to JSON is when some property in the object is repeated in another inner object.
Axios response has these properties:
// `data` is the response that was provided by the server
data: {..your real json response..},
// `status` is the HTTP status code from the server response
status: 200,
// `statusText` is the HTTP status message from the server response
statusText: 'OK',
// `headers` the HTTP headers that the server responded with
headers: {},
// `config` is the config that was provided to `axios` for the request
config: {},
// `request` is the request that generated this response
request: {}
If you send the entire axios response object to be converted to json, some property in your real json response could repeat the name of private axios properties like: status, data config, etc
Fix
Try with ax.data instead use the entire axios response ax

How to get raw response data from axios request?

I am making a request to an API in which they sign their response body with a private key and send me the signature in a header. I am supposed to use their public key to validate the signature with the original response body but at the moment axios parses the response data there is something that is changing in it which makes the signature invalid. Is there some way to get the raw response data with axios?
I am doing a post request and want to get the string of the JSON object that axios automatically parses for me.
You can set a "identity" transformResponse.
let res = axios.get("url",
{ transformResponse: (r) => r }); //null transform (we do not want to parse as JSON);
//res.data should now contain a plain unparsed string
Not sure if setting transformResponse to null does the same thing as the identity transform.

Return JSON response in ISO-8859-1 with NodeJS/Express

I have built an API with Node and Express which returns some JSON. The JSON data is to be read by a web application. Sadly this application only accepts ISO-8859-1 encoded JSON which has proven to be a bit difficult.
I can't manage to return the JSON with the right encoding even though I've tried the methods in the Express documentation and also all tips from googling the issue.
The Express documentation says to use "res.set()" or "res.type()" but none of these is working for me. The commented lines are all the variants that I've tried (using Mongoose):
MyModel.find()
.sort([['name', 'ascending']])
.exec((err, result) => {
if (err) { return next(err) }
// res.set('Content-Type', 'application/json; charset=iso-8859-1')
// res.set('Content-Type', 'application/json; charset=ansi')
// res.set('Content-Type', 'application/json; charset=windows-1252')
// res.type('application/json; charset=iso-8859-1')
// res.type('application/json; charset=ansi')
// res.type('application/json; charset=windows-1252')
// res.send(result)
res.json(result)
})
None of these have any effect on the response, it always turns into "Content-Type: application/json; charset=utf-8".
Since JSON should(?) be encoded in utf-8, is it event possible to use any other encoding with Express?
If you look at the lib/response.js file in the Express source code (in your node_modules folder or at https://github.com/expressjs/express/blob/master/lib/response.js) you'll see that res.json takes your result, generates the corresponding JSON representation in a JavaScript String, and then passes that string to res.send.
The cause of your problem is that when res.send (in that same source file) is given a String argument, it encodes the string as UTF8 and also forces the charset of the response to utf-8.
You can get around this by not using res.json. Instead build the encoded response yourself. First use your existing code to set up the Content-Type header:
res.set('Content-Type', 'application/json; charset=iso-8859-1')
After that, manually generate the JSON string:
jsonString = JSON.stringify(result);
then encode that string as ISO-8859-1 into a Buffer:
jsonBuffer = Buffer.from(jsonString, 'latin1');
Finally, pass that buffer to res.send:
res.send(jsonBuffer)
Because res.send is no longer being called with a String argument, it should skip the step where it forces charset=utf-8 and should send the response with the charset value that you specified.

How to return JSON without re-serialization in ServiceStack service?

In my service implemented in ServiceStack I already have response object serialized to JSON string. How can I return it without being serialized as a string? I would like to avoid deserializing it into DTO instance only to be serialized back by ServiceStack.
Here's a snippet where I load a json file off disc:
if (File.Exists(jsonFileLocation))
{
return new HttpResult(new FileInfo(jsonFileLocation), asAttachment: false,
contentType: ContentType.Json);
}

Servicestack accessing json

My Servicestack service is beeing posted Json (by jquery).
sendData = function(dataToSend) {
var request;
return request = $.ajax({
url: "/api/test",
type: "post",
data: JSON.stringify(dataToSend),
dataType: "json",
accept: "application/json",
contentType: "application/json"
});
The Json data is correctly deserialized if it corresponds to the root properties of my DTO (eg: userId:'foo' -> UserId=foo in the DTO).
I want to access the raw json posted data before it gets deserialized for adding custom deserialization.
Till now I had no problems accessing the querystrings with custom filters (RequestFilterAttribute) or if data vas posted like form.
Now I see the data that gets posted with Chrome Developer Tools is in the headers with "Request Payload" so it is nor in FormData and nor QueryString I can access when debugging my IHttpRequest.
How can I get my raw json data in the filter?
If you want to replace the default deserialization behavior with custom behavior for a specific request DTO, you can do this in your AppHost setup code:
JsConfig<MyRequestDtoClass>.DeSerializeFn = DeserializeMyRequestDto;
Where DeserializeMyRequestDto is a function or lambda taking a single string param - the raw request body - and returning the deserialized instance of your DTO:
MyRequestDtoClass DeserializeMyRequestDto(string rawBody) { ... }
RequestFilterAttribute subclasses purpotedly have access to the raw request body using request.GetRawBody(), where request is the IHttpRequest object passed into the filter's Execute method. But in my experience, GetRawBody returns an empty string, because the request input stream seems to be consumed by that time due to the deserialization. I worked around this once by creating an HTTP module (registered in AppHost via DynamicModuleUtility.RegisterModule) that would "peek" at the request input stream in a BeginRequest event handler. (The "peek" function would read the request input stream and then reset the Position of the stream to where it initially was.)

Resources