             return nil
         }
 
-        var task: URLSessionDataTask?
-        task = FaroURLSession.urlSession?.dataTask(with: request, completionHandler: {[weak self] (data, response, error) in
+        var task: URLSessionTask!
+
+        if call.httpMethod == .GET  {
+            task = FaroURLSession.urlSession?.downloadTask(with: request)
+        } else if let body = request.httpBody {
+            task = FaroURLSession.urlSession?.uploadTask(with: request, from: body)
+        } else {
+            task = FaroURLSession.urlSession?.dataTask(with:request)
+        }
+
+        session.tasksDone[task] = {[weak self] (data, response, error) in
             guard let task = task else {
-                let error = ServiceQueueError.invalidSession(message: "Task should never be nil!", request: request)
+                let error = ServiceError.networkError(-1, data: data, request: request)
                 self?.handleError(error)
-                self?.invalidateAndCancel()
                 complete {throw error}
                 return
             }

    private func shouldCallFinal() {
        if !hasOustandingTasks {
            final(failedTasks)
            FaroURLSession.urlSession?.finishTasksAndInvalidate()
        }
    }

    // MARK: - Invalidate session overrides

    open func invalidateAndCancel() {
        taskQueue.removeAll()
        failedTasks?.removeAll()
        FaroURLSession.urlSession?.invalidateAndCancel()
    }

    deinit {
        FaroURLSession.urlSession?.finishTasksAndInvalidate()
    }

}

    /// - parameter session: a session must have a backendConfiguration set.
    /// - parameter final: closure is callen when all requests are performed.
	public init (session: FaroURLSession, final: @escaping(_ failedTasks: Set<URLSessionTask>?)->()) {
        taskQueue = Set<URLSessionTask>()
        self.final = final
        self.session = session
	}
