1

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.

Vik Singh
  • 1,563
  • 2
  • 19
  • 36
  • What happens if you try from Terminal to call your server e.g. using `curl -v [url]`? – Pol Feb 02 '16 at 00:12
  • @Pol: I just updated my question with the results I saw after using curl command in the terminal – Vik Singh Feb 02 '16 at 01:21
  • I don't program in Swift so I can't help much, but if you step through your handlers using the Xcode debugger, you should be able to figure out what's happening. Also be sure to install your handlers in the right order since last one installed is called first with the request. – Pol Feb 02 '16 at 05:18

1 Answers1

0

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.

Vik Singh
  • 1,563
  • 2
  • 19
  • 36