2016-09-21 2 views
0

Ich versuche, eine sehr spezifische HTTP-Anforderung an einen Server herstellt (dh. Die Definition der genaue Satz von HTTP-Header), aber NSURLSession hält „helfend“ eine Reihe von HTTP-Header wie Accept Einfügen , Accept-Language und Accept-Encoding.Verhindern NSURLSession Standard-HTTP-Header

Betrachten Sie den folgenden Spielplatz (Swift 2.x), die eine Anforderung an einen Dienst sendet, die nur die HTTP-Header Echos, die gesendet wurden:

import Foundation 
import XCPlayground 

XCPlaygroundPage.currentPage.needsIndefiniteExecution = true 

let url = NSURL(string: "http://httpbin.org/headers")! 
let request = NSMutableURLRequest(URL: url, cachePolicy: .ReloadIgnoringLocalCacheData, timeoutInterval: 30000) 
let configuration = NSURLSessionConfiguration.ephemeralSessionConfiguration() 
let session = NSURLSession(configuration: configuration) 

let task = session.dataTaskWithRequest(request) { (data: NSData?, response: NSURLResponse?, error: NSError?) in 
    print(NSString(data: data!, encoding: NSUTF8StringEncoding)) 
    XCPlaygroundPage.currentPage.finishExecution() 
} 
task.resume() 

Sie können sehen, dass es drei Accept Header sein geschickt. Wie kann ich das verhindern?

Ich habe versucht, die Kopfzeile mit request.setValue(nil, forHTTPHeaderField: "Accept-Language") Einstellung, aber das wird ignoriert. Versucht, es auf "" einzustellen, aber nicht gut. Ich habe auch versucht, die HTTPAdditionalHeaders Eigenschaft auf NSURLSessionConfiguration zu manipulieren, aber keine Liebe.

Wie bekomme ich NSURLSession, um nicht ganz so hilfreich zu sein?

Antwort

1

Ich bezweifle, was Sie verlangen, ist möglich. NSURLSession (und NSURLConnection) stellen automatisch eine Anzahl von Headern bereit, und das ist einer davon.

Es gibt auch keinen gültigen Grund, sie zu entfernen. Alle drei dieser Header sind seit der ursprünglichen Spezifikation HTTP/0.9 (https://www.w3.org/Protocols/HTTP/HTRQ_Headers.html) Teil der Spezifikation. Es gibt absolut keine Entschuldigung für irgendeinen Server, der diese nicht richtig behandelt oder sie direkt ignoriert.

Mit dem gesagt, wenn Sie den falschen Wert für diese Felder angeben (und der Standardwert möglicherweise falsch ist), kann der Server verweigern, Ihnen Ergebnisse zu geben. Um dieses Problem zu lösen, ermitteln Sie zuerst, welche Art von Daten der Server tatsächlich bereitstellen wird, und geben Sie diesen Wert im Accept-Header anstelle des Standardwerts an.

Sie können beispielsweise Accept auf "application/json" oder eine der anderen Varianten (What is the correct JSON content type?) setzen, wenn Sie JSON-Daten erwarten.

Das heißt, wenn Sie wirklich vermeiden müssen diese Header gesendet haben, können Sie immer einen Socket öffnen, erstellen Sie die Anfrage manuell, und senden Sie es. Angenommen, der Server benötigt keine Chunked-Codierung, ist dies ziemlich einfach. (Die Chunked-Codierung ist jedoch ein Horror herkulischer Proportionen. Wenn Ihr Server das zurücksendet, müssen Sie ziemlich schnell auf das Hinzufügen von libcurl in Ihr Projekt zurückgreifen und stattdessen Anfragen stellen.)

+0

Vielen Dank für Ihre Nachricht Gedanken. Mein Fall ist etwas Besonderes, da meine App (serveuppapp.com) eingehende Anfragen von einer entfernten Quelle akzeptiert (wahrscheinlich eine mobile App, die gerade entwickelt wird) und entweder eine verspottete Antwort zurückgibt oder sie an den realen Server weiterleitet. Ich möchte die genaue Menge der Header, die ich erhalte, wirklich treu weiterleiten ... wie du sagst, ist es fast sicher, dass ich diese Header tatsächlich erhalten werde, aber ich versuche nur darüber nachzudenken, wie ich mit dem Fall umgehen werde t. –

+0

Betrachtet man den Swift Open Source Code (https://github.com/apple/swift-corelibs-foundation/blob/db54d310bf348de6834d1ec9f83721d403100ccf/Foundation/NSURLSession/NSURLSessionTask.swift#L594), sieht es so aus, als ob alles an libcurl delegiert wird. Unglücklicherweise scheint die Art und Weise, wie 'NSURLSession' und seine Freunde strukturiert sind, diese Methoden ein wenig knifflig zu machen, ohne einen Haufen brüchiger Magie, die sich zwischen den Releases ändern könnte. Ich muss vielleicht damit leben. –

+0

Was Sie dort sehen, ist nicht der eigentliche Foundation-Netzwerk-Quellcode. Das ist eine Kompatibilitätsschicht, die Apple zur Verfügung gestellt hat, damit die kritischsten Teile von NSURLSession auf Nicht-Mac-Plattformen verwendet werden können.Daher fehlen viele Dinge, zum Beispiel Hintergrundsessions. Die eigentliche NSURLSession-Implementierung ist in Objective-C geschrieben und IIRC ist eine ziemlich dünne Schicht über CFNetwork, die in C/C++ geschrieben ist. Es sei denn, Sie verwenden diese API unter Linux oder einem anderen Betriebssystem. – dgatwood