Swift-ActionCableClient icon indicating copy to clipboard operation
Swift-ActionCableClient copied to clipboard

Headers not being assigned

Open NicosKaralis opened this issue 6 years ago • 2 comments

After some debugging I've found that the headers setter is calling the getter which calls a dynamic getter and ignores the new values

This declaration

    open var headers : [String: String]? {
        get { return socket.request.allHTTPHeaderFields }
        set {
            for (field, value) in headers ?? [:] {
                socket.request.setValue(value, forHTTPHeaderField: field)
            }
        }
    }

Should be replaced with this

    open var headers : [String: String]? {
        get { return socket.request.allHTTPHeaderFields }
        set {
            for (field, value) in newValue ?? [:] {
                socket.request.setValue(value, forHTTPHeaderField: field)
            }
        }
    }

If you need a test just run this example

  let client: ActionCableClient = {
    let _client = ActionCableClient(url: Defaults.Api.cableURL)
    _client.headers = [
      "Origin": "https://server.example"
    ]
    return _client
  }()
  print(client.headers)
  client.headers = [
    "Origin": "https://server.example",
    "Accept": "accept/json"
  ]
  print(client.headers)
  if !client.isConnected {
    client.connect()
  }

https://github.com/danielrhodes/Swift-ActionCableClient/blob/master/Source/Classes/ActionCableClient.swift#L77

NicosKaralis avatar Nov 19 '18 19:11 NicosKaralis

After more headscreatching I've found another problem with variable names.

My server handles authentication via the Authorization header and it rejects the connection if the token is not right. But for some reason the client never got the message and kept retrying

This was the offending code on Error.swift:

    init(from error: Swift.Error) {
      switch error._code {

._code is a private variable and should not be used to identify the error. Since the error received is a WSError a more sane approach would be.

    init(from error: Swift.Error) {
      let error_code: Int
      if let ws_error = error as? WSError {
        error_code = ws_error.code
      } else {
        error_code = error._code
      }
      
      switch error_code {

We look for an WSError if it is not the correct class then we use a fallback

I'll update the pull request to include this fix

NicosKaralis avatar Nov 19 '18 20:11 NicosKaralis

https://github.com/nerzh/Action-Cable-Swift

nerzh avatar Aug 31 '20 20:08 nerzh