evgenyneu / moa

An image download extension of the image view written in Swift for iOS, tvOS and macOS.
MIT License
332 stars 45 forks source link

moa.MoaError.notAnImageContentTypeInResponseHttpHeader #18

Open hajjarjoseph opened 4 years ago

hajjarjoseph commented 4 years ago

Getting this error while trying to load certain images ( some work, other don't ) moa.MoaError.notAnImageContentTypeInResponseHttpHeader Library setup method: CocoaPods. Version of the library: 11.0.1 Xcode version: 11.1 OS version. Example: iOS 13.0

evgenyneu commented 4 years ago

Thanks for reporting @hajjarjoseph. Could you share an image URL that's causing this issue, so I can reproduce the problem?

hajjarjoseph commented 4 years ago

Yes please try this : url

hajjarjoseph commented 4 years ago

(It was working fine before migrating to swift 4.2)

evgenyneu commented 4 years ago

Hi, the "Content-Type" response header value for this URL is "application/octet-stream" instead of "image/jpeg". Moa checks the content type before showing the image to make sure the data received is actually an image. This is why it throws notAnImageContentTypeInResponseHttpHeader exception for this URL.

One can check the repose headers with the curl -I YOUR_URL command:

(base) Downloads $ curl -I https://achghali.s3.amazonaws.com/4d9e6341631cf1c7f51d9b329bc491f0_image.jpg
HTTP/1.1 200 OK
x-amz-id-2: x9SP35ZhzJeAjy7LGaq3odaUQuh4xkrVimuvrH+q36Qbm8Oss7WXQCzQ9A3jijbLfNb86UHuI8Y=
x-amz-request-id: 10B214CFB4E1404B
Date: Mon, 14 Oct 2019 20:04:15 GMT
Last-Modified: Mon, 14 Oct 2019 09:33:11 GMT
ETag: "a883b9d70edd3ed0591eaf8993003712"
Accept-Ranges: bytes
Content-Type: application/octet-stream
Content-Length: 27026
Server: AmazonS3

Let me know if it helps. :)

Aviral190694 commented 4 years ago

I am also facing the same issue. If you try to use moa from xcode 10.3 the same image works okay but fails to work in xcode 11.

Aviral190694 commented 4 years ago

Just to give a quick summary of the issue : `static func handleSuccess(_ data: Data?, response: HTTPURLResponse, onSuccess: (MoaImage)->(), onError: (Error, HTTPURLResponse?)->()) {

// Show error if response code is not 200
if response.statusCode != 200 {
  onError(MoaError.httpStatusCodeIsNot200, response)
  return
}

// Ensure response has the valid MIME type
if let mimeType = response.mimeType {
  if !validMimeType(mimeType) {
    // Not an image Content-Type http header
    let error = MoaError.notAnImageContentTypeInResponseHttpHeader
    onError(error, response)
    return
  }
} else {
  // Missing Content-Type http header
  let error = MoaError.missingResponseContentTypeHttpHeader
  onError(error, response)
  return
}

if let data = data, let image = MoaImage(data: data) {
  onSuccess(image)
} else {
  // Failed to convert response data to UIImage
  let error = MoaError.failedToReadImageData
  onError(error, response)
}

}`

in the above function in class MoaHttpImage.swift The method to get mimeType is messing up in xcode 11.1 where it is getting mime type as application/octet-stream And where as on xcode 10.3 : the same file show up as mime type as image/jpeg.

To fix it I added "application/octet-stream" to the list of mime and everything is working okay for now.

evgenyneu commented 4 years ago

@Aviral190694, thanks for researching this. It looks like Apple has made some changes that broke moa for those MIME types. From iOS 13 Release Notes:

To enhance security, URLSession no longer sniffs the MIME type when the server sends Content-Type: application/octet-stream. (7820658)

I've whitelisted application/octet-stream MIME type, this is now available in version 12 of moa. Thanks for your help!

Aviral190694 commented 4 years ago

@evgenyneu glad I can help.