Search code examples
swift2ios9gcdwebserver

GCDWebServerFileResponse fails with ErrorCode=-1017 "cannot parse response"


I am trying to send a file from one device to another using GCDWebServerFileResponse but I am getting following error everytime:

Optional(Error Domain=NSURLErrorDomain Code=-1017 "cannot parse response" UserInfo={NSUnderlyingError=0x14e6d46a0 {Error Domain=kCFErrorDomainCFNetwork Code=-1017 "(null)" UserInfo={_kCFStreamErrorCodeKey=-1, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=http://xx.xx.xx.xx:8080/course.json, NSErrorFailingURLKey=http://xx.xx.xx.xx:8080/course.json, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-1, NSLocalizedDescription=cannot parse response})

Following is my GET Request code:

func sendGetRequestToTeacher(data: AnyObject, IP: String, completionHandler: ((Bool, AnyObject) -> Void)? = nil) {
    let archivedData = NSKeyedArchiver.archivedDataWithRootObject(data)
    let url = NSURL(string: ("http://" + IP + ":\(self.port)/" + "course.json"))!
    let request = NSMutableURLRequest(URL: url, cachePolicy: NSURLRequestCachePolicy.UseProtocolCachePolicy, timeoutInterval: 30.0)
    request.networkServiceType = NSURLRequestNetworkServiceType.NetworkServiceTypeVoIP
    request.HTTPMethod = "GET"
    request.HTTPBody = archivedData
    request.setValue("application/octet-stream", forHTTPHeaderField: "Accept")
    request.setValue("application/octet-stream", forHTTPHeaderField: "Content-Type")
    request.setValue("\(archivedData.length)", forHTTPHeaderField: "Content-Length")

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data, response, err) -> Void in
        dispatch_async(dispatch_get_main_queue(), { () -> Void in
            if let err = err {
                completionHandler?(false, err)
            } else if let data = data, let unarchivedData = NSKeyedUnarchiver.unarchiveObjectWithData(data) {
                completionHandler?(true, unarchivedData)
            }
        })
    })
    task.resume()
}

and this is my GET Handler:

private func addDefaultHandlerForGetMethod() {
    self.server.addGETHandlerForBasePath("/", directoryPath: "/", indexFilename: nil, cacheAge: 3600, allowRangeRequests: true)
}

private func addHandlerForGetMethod() {
    self.server.addHandlerWithMatchBlock({ (requestMethod, requestURL, requestHeaders, urlPath, urlQuery) in
        if requestMethod != "GET" {
            return nil
        }
        if !urlPath.hasSuffix("/course.json") {
            return nil
        }
        return GCDWebServerRequest(method: requestMethod, url: requestURL, headers: requestHeaders, path: urlPath, query: urlQuery)
        }, processBlock: { (request) in
            let filePath = STCCourseManager.sharedInstance.coursesFolderPath.stringByAppendingPathComponent((STCCourseManager.sharedInstance.currentCourseID?.stringByAppendingPathComponent(request.path.stringByRemovingPercentEncoding!))!)
            do {
                let fileAttributes = try NSFileManager.defaultManager().attributesOfItemAtPath(filePath)
                if let fileType = fileAttributes[NSFileType] as? String where fileType == NSFileTypeRegular {
                    let response = GCDWebServerFileResponse(file: filePath, byteRange: request.byteRange)
                    response.setValue("bytes", forAdditionalHeader: "Accept-Ranges")
                    response.cacheControlMaxAge = 3600
                    return response
                }
            } catch {
                print("\(error)")
            }
            return GCDWebServerResponse(statusCode: GCDWebServerClientErrorHTTPStatusCode.HTTPStatusCode_NotFound.rawValue)
    })

Also, I just realized that if I use curl -v http://127.0.0.1:8080/fileURL, the request is handled by the defaultHandlerForGet and it returns the file properly in the terminal, however my custom handler returns "Not Found". what am I missing in my custom handler?

I would really appreciate any help in resolving this issue.


Solution

  • I was able to solve this issue by changing my request to following:

        let url = NSURL(string: ("http://" + IP + ":\(self.port)/" + "distribution"))!
        let request = NSMutableURLRequest(URL: url)
        request.timeoutInterval = 30.0
    

    Not Sure what was wrong with the previous request thigh. May be I had some header field set incorrectly. Because of the lack of any answers, I am accepting this solution.