Error fetch image from storage with message 'Alamofire.AFError.ResponseValidationFailureReason.unacceptableContentType' - swift

I attemp to fetch image from Firebase storage, but have error message:
Alamofire.AFError.responseValidationFailed(reason: Alamofire.AFError.ResponseValidationFailureReason.unacceptableContentType(acceptableContentTypes: ["image/x-xbitmap", "image/jpeg", "application/octet-stream", "image/gif", "image/ico", "image/tiff", "image/x-icon", "image/bmp", "image/x-bmp", "image/x-win-bitmap", "image/png", "image/x-ms-bmp"], responseContentType: "application/json")
My url looks like this: https://firebasestorage.googleapis.com/v0/b/####/o/executors/o4uAQa158nXTvJ5omuxqcRb0e793/products/7DDCEEAC-ED54-4910-B93D-5E40BF411B80
I can download this image via browser.
My image has MIME-type 'image/jpeg':
I found the same situation:
Response Content-Type was missing and acceptable content types
Make sure you set alamofire acceptable content types
Image Response Serializers
These hints didn't help me to fix my bug.
Version of pod:
Alamofire: 5.0.2
AlamofireImage 4.0.2
Initially I used AlamofireImage: productImageView.af.setImage(withURL: url), but it didn't work. Then I began using Alamofire. And into request I pass MIME-type image/jpeg like Content-Type:
And I decided to use this approach to fix bug, but has the same error and I don't understand why(from docs):
If you can see in error-message I have:
responseContentType: "application/json"
So does it have any side effect to fetch image? What I do wrong at all?

Link should be
https://firebasestorage.googleapis.com/v0/b/projectname/o/image.png?alt=media&token=auth_token
replace projectname , image name and token to yours

First, your request headers have nothing do with whether the response is valid, so adding image/jpeg there won't help. Second, your response is return an application/json content type, so adding image/jpeg to the acceptable content types won't help (and image/jpeg is already acceptable). (As an aside, you need to import AlamofireImage to get addAcceptableImageContentTypes to work.)
In the end, you should ensure you're getting the response you expect, as an application/json content type implies you're getting a JSON body, not an image fro your request. When I request the URL you posted, I get this JSON response:
{
"error": {
"code": 400,
"message": "Invalid HTTP method/URL pair."
}
}
So most likely you need to double check how you're supposed to be making the request.

Related

is there any way how can I properly use multipart/form-data and the proper body format in API testing for TestProject?

Below are my inputs in TestProject;
*screenshot of Testproject inputs
{AttachmentRequestBody} = {"fileName": "Capture.png", "name": "file", "Content-Disposition": "form-data", "Content-Type": "image/png"}
Please correct me if I inputted a wrong key and value in the request body
*screenshot of FilePath input in TestProject
And I'm getting a response code 400 and also below is the screenshot of the response body
Server responded with status code 400 instead of expected 200 status code.
Server returned response body:
{"errors":{"":["Failed to read the request form. Missing content-type boundary."]},"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"00-df4bc25f2925a54e902eb589f9a4bb65-851ad16fccaeb34b-00"}
*screenshot of the response body
Hope you guys can help me on this one. Thanks!

HTTPie returning "Error processing request. All request parts must have the content-type header set."

I'm testing an API with HTTPie. The implementation notes of the method I'm trying to use states that it accepts a multipart query containing a model in JSON format (Content-Type=application/json) and one or several files (Content-Type=application/octet-stream). I'm trying to post a file accompanied by a model in JSON. According to what I understood from the HTPPie documentation the way to do it is passing it as form:
http --form POST https://smartcat.ai/api/integration/v1/project/document documentModel#/path/to/json/file taskfile#/path/to/file\ projectId==xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx
where projectId is a parameter to be sent as query string.
I've tried to set a Content-Type header for each file, however it doesn't seem right, as I expected the --form flag to set content-type as multipart/form-data, according to the documentation.
I'm sure I'm missing something basic, so any ideas on the direction to follow and how to better understand mime types are very welcome.

POST image to web service with Flutter

I am currently using Flutter and Dart to try to send an image to a web service, after which I wait for a JSON response. The below links show the Postman request that I am trying to mimic.
An image of Postman with the headers required
An image of Postman with the body
I think the issue I am having is either not setting the headers of my request correctly, or not encoding the image correctly.
Currently I am getting a HTTP 400 error.
I have tried following these suggested solutions on StackOverflow but have been getting the HTTP 400 error.
Any help would be much appreciated!
Try this. I'd suggest creating yourself a plain Dart project, if you haven't already. This way you can test things without the need of the phone emulator, etc.
main() async {
http.MultipartRequest request =
new http.MultipartRequest('POST', Uri.parse(url));
request.headers['Prediction-Key'] = '3f4a......'; // todo - insert real value
request.files.add(
new http.MultipartFile.fromBytes(
'image',
bytes,
filename: 'somefile', // optional
contentType: new MediaType('image', 'jpeg'),
),
);
http.StreamedResponse r = await request.send();
print(r.statusCode);
}
If the file is on disk, not in memory, then use the fromPath named constructor instead. Experiment with different media types. I've used image/jpeg, but you could try application/octet-stream.
As an aside, in your first screenshot you show a content type, but Postman ignores this as the overall content type is overridden by multipart-form. Uncheck that row in Postman to prove this.
There was another question recently on SO, where the server was incorrectly expecting headers to be case sensitive. In postman, try again with lowercase prediction-key to prove that the server doesn't mind lowercase headers (which is what Dart uses).

How to set Content-Type in swift3 alamofire

I am sending data in JSON with content-type JSON but this shows me the content-type XML.
So the server could not read my request.
Also, that is the post request
The problem is that you are using .responseJSON which tells Alamofire that the response would contain JSON. Since the response is XML and not JSON in your case, Alamofire would throw an error. What you need instead is not to specify the response type and then an XMLParser to parse the data. One option is SWXMLHash. Your updated code would look something like this
Alamofire.request(request)
.response { response in
var xml = SWXMLHash.parse(response.data!)
}
Basically, this is not an error of content-type. this is an error of data type.
I send the all value in the string but there is need to send the data with data type.
When I request with data type it automatically changed content-type in JSON.

Which HTTP code should be return from REST API?

im currently working on a website which has Spring at backend and Angularjs at front side and we had discussed about back end responses to handle frontend's message dialogs and i have a question to ask:
Lets say i have an API :
GET : /getstatistics
Request params : fromTime,toTime ( in timestamp format)
And if client make a request with invalid params like a string, which response code should be returned from server ? HTTP 400 bad request and response body with a message " fromTime and toTime should be in timestamp format" or HTTP 200 with same message?
I saw some Google's APIs for example Oauth, they're returning code 200 for a request with invalid access_token but ,in our project my opinion it should be HTTP 400 because Javascript has success and error callbacks, is it better for it just pop a red color dialog with message inside rather than a HTTP 200 code then still need to check the content of the message?
Any advides and opinions are appreciated.
Thanks!
You should be returning a 400 error for bad request. Check out this reference.
The server cannot or will not process the request due to something
that is perceived to be a client error (e.g., malformed request
syntax, invalid request message framing, or deceptive request
routing).
Please have a look at RFC7231#section-6
A client MUST understand the class of any status code, as indicated by
the first digit
and,
4xx (Client Error): The request contains bad syntax or cannot be
fulfilled
Bad syntax can be something like you've mentioned in your question (making a request with invalid parameters, like a string).
I keep these two references handy whenever I'm designing RESTful APIs, might be helpful for you too:
https://httpstatuses.com/
http://www.restapitutorial.com/httpstatuscodes.html
Yes you are right, the http code should be 400 in your case. Your discussion here normally should be whether you need to return 400 or 422. For this you can check the accepted response for this SO question 400 vs 422 response to POST of data
I think it has something to do with how the parameters are used. If you use the resource, then a 404 should return. If the data is simply not valid then we decide to set a 409 Status to the request. It can't full fill it at 100% because of missing/invalid parameter.
HTTP Status Code "409 Conflict" was for us a good try because it's
definition require to include enough information for the user to
recognize the source of the conflict.
Reference: w3.org/Protocols/
Edit:
In any case, the status code 200 is incorrect here because there is an error. In response, you can then return specific information like this:
{
"errors": [
{
"userMessage": "Sorry, the parameter xxx is not valid",
"internalMessage": "Invalid Time",
"code": 34,
"more info": "http://localhost/"
}
]
}