NSURLConnection und 404

  • NSURLConnection und 404

    Moin,

    mal wieder ich mit merkwürdigen Problemen. Ich benutz ein einem Programm eine NSURLConnection. Funktioniert auch für existente Dateien wunderbar.

    Erfolgt jetzt eine Anfrage für eine nicht existente Datei (also mit Status 404 im Falle von HTTP) nibbelt mir das ganze sang- und klanglos ab:

    #0 0x907eff20 in CFRunLoopWakeUp ()
    #1 0x9298ed18 in -[NSURLConnection(NSURLConnectionInternal) _postCallback:] ()
    #2 0x92991250 in -[NSURLConnection(NSURLConnectionInternal) _postDidReceiveResponseCallback] ()
    #3 0x92992104 in -[NSConnectionHTTPURLProtocol performStreamRead:] ()
    #4 0x9298c80c in readStreamCallback2 ()
    #5 0x90829eb4 in _CFStreamSignalEventSynch ()
    #6 0x907dd584 in __CFRunLoopDoSources0 ()
    #7 0x907dc9fc in __CFRunLoopRun ()
    #8 0x907dc47c in CFRunLoopRunSpecific ()
    #9 0x9298669c in +[NSURLConnection(NSURLConnectionInternal) _resourceLoadLoop:] ()
    #10 0x9295f194 in forkThreadForFunction ()
    #11 0x9002b508 in _pthread_body ()


    Das "witzige" ist daß
    - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
    nicht aufgerufen wird.

    Ich hab schon Folgendes probiert:

    Quellcode

    1. - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
    2. {
    3. // is it an NSHTTPURLResponse?
    4. if ([response respondsToSelector:@selector(statusCode)])
    5. {
    6. int status = [(NSHTTPURLResponse*)response statusCode];
    7. if (!((status >= 200) && (status < 400)))
    8. {
    9. .
    10. .
    11. .
    Alles anzeigen


    Aber -- da kommt er leider nie hin.

    Wie gesagt, für existente Dateien funktioniert das wunderbar. -- Hat jemand eine Idee?
    if (!exit(-1)) fprintf(stderr, "exit call failed. Program will continue\n");
  • RE: NSURLConnection und 404

    Hi,
    ich habe bisher nur ein bisschen mit NSURLDownload rumgemacht. -> /Developer/Examples/WebKit/Downloader. Vielleicht reicht dir das ja schon.
    Apple schreibt in NSURLDownload and NSURLConnection Differences
    One of the significant differences between NSURLConnection and NSURLDownload is the handling of requests for non-existent URLs when web server has be configured to return an alternate page in response to an error.

    When using NSURLConnection the default behavior is to allow the redirect and return the contents of the redirected URL, instead of returning an error. If an attempt is made to download the same URL using NSURLDownload, an error is returned indicating that the file has not been found.

    An NSURLConnection delegate can mimic the NSURLDownload behavior by implementing the connection:willSendRequest:responseRequest: method, and examining the provided NSURLResponse. If the response is an NSHTTPURLResponse object, and the statusCode is 4xx or 5xx, then the server is attempting to redirect to an alternate error page. The delegate can prevent this by returning nil.


    Chris
    Man macht einfach solange irgendwelche Dinge, bis man tot ist.
    Und dann bekommen die anderen Kuchen.
  • Der Witz an der Sache ist... Ich habe - (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response mal eingebaut; das wird exakt gar nicht aufgerufen, er stürzt einfach nur weiter ab.

    Jemand ne Idee?
    if (!exit(-1)) fprintf(stderr, "exit call failed. Program will continue\n");
  • Hast du das:
    Handling of Non-existent URLs

    One of the significant differences between NSURLConnection and NSURLDownload is the handling of requests for non-existent URLs when web server has be configured to return an alternate page in response to an error.

    When using NSURLConnection the default behavior is to allow the redirect and return the contents of the redirected URL, instead of returning an error. If an attempt is made to download the same URL using NSURLDownload, an error is returned indicating that the file has not been found.

    An NSURLConnection delegate can mimic the NSURLDownload behavior by implementing the connection:willSendRequest:responseRequest: method, and examining the provided NSURLResponse. If the response is an NSHTTPURLResponse object, and the statusCode is 4xx or 5xx, then the server is attempting to redirect to an alternate error page. The delegate can prevent this by returning nil.


    Quellcode

    1. - (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response
    kommt wenn ich das richtig Verstehe nur zum Zuge, wenn wenn eine HTTP weiterleitung geschickt wird, was im normalfall nicht passiert..

    Quellcode

    1. connection:willSendRequest:responseRequest:
    sollte immer funktionieren.
    the default behavior is to allow the redirect
    Bezieht sich nicht auf die Response, sondern eben darauf, das NSURLConnection den Redirect erlaubt. Geschickt wird der vom Server im Normalfall nicht.

    (Alles Theorie, hab gerade keinen Mac)
    Seminare, Artikel, Code. ObjectiveCeeds - alles für die Apfelzucht.
  • Original von kressevadder

    Quellcode

    1. connection:willSendRequest:responseRequest:
    sollte immer funktionieren.

    Ist tatsächlich Theorie. Laut Mail-Archiven handelt es sich dabei um einen Tippfehler in der Doku.
    Ich habe mir mal mit respondsToSelector ausgeben lassen, auf was mein Delegate denn alles geprüft wird und da ist tatsächlich nur connection:willSendRequest:redirectResponse: dabei, connection:willSendRequest:responseRequest: aber nicht...
    if (!exit(-1)) fprintf(stderr, "exit call failed. Program will continue\n");
  • Original von kressevadder
    #10 0x9295f194 in forkThreadForFunction ()
    Schubst du die Connection in einen neuen Thread?

    Nein.
    Wie gesagt, für existente URLs funktioniert das ganze tadellos.
    if (!exit(-1)) fprintf(stderr, "exit call failed. Program will continue\n");
  • Da kommt er leider gar nicht erst hin. :(

    Nachdem ich die

    Quellcode

    1. - (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response

    eingebaut habe verabschiedet er sich jetzt übrigens reproduzierbar so:
    #0 0x907eff20 in CFRunLoopWakeUp ()
    #1 0x9298ed18 in -[NSURLConnection(NSURLConnectionInternal) _postCallback:] ()
    #2 0x92991250 in -[NSURLConnection(NSURLConnectionInternal) _postDidReceiveResponseCallback] ()
    #3 0x92992104 in -[NSConnectionHTTPURLProtocol performStreamRead:] ()
    #4 0x9298c80c in readStreamCallback2 ()
    #5 0x90829eb4 in _CFStreamSignalEventSynch ()
    #6 0x907dd4cc in __CFRunLoopDoSources0 ()
    #7 0x907dc9fc in __CFRunLoopRun ()
    #8 0x907dc47c in CFRunLoopRunSpecific ()
    #9 0x9298669c in +[NSURLConnection(NSURLConnectionInternal) _resourceLoadLoop:] ()
    #10 0x9295f194 in forkThreadForFunction ()
    #11 0x9002b508 in _pthread_body ()


    Bei

    Quellcode

    1. - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
    kommt er aber nie an.

    Hmm...
    if (!exit(-1)) fprintf(stderr, "exit call failed. Program will continue\n");
  • hmm ich vertstehe wohl das grundproblem nicht. bei meiner kleinen app mit NSURLConnection bekomme ich entweder die 404 fehlerseite zurueckgeliefert oder

    Quellcode

    1. - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
    wird aufgerufen.

    hast du da ein kleines test project zur verdeutlichung?

    gruss
    j.
    malloc: *** vm_allocate(size=1665622016) failed (error code=3)
  • Original von kressevadder
    Mal ungeachtet der Tatsache, daß das normalerweise funktioniert: Was soll dieses

    forkThreadForFunction ()

    NSURLConnection läuft doch IMHO nicht in einem eigenen Thread.

    Und wenn du mal nach _pthread_body googlest findest du jede Menge Hilferufe von Leuten, denen iTunes oder sonst was beim Update abrauscht...

    Die Frage ist: bringt mir das was? Das ganze läuft deifinitiv im Hauptthread.
    Original von Jens
    hast du da ein kleines test project zur verdeutlichung?

    Puh, da wird mir wohl nichts anderes übrigbleiben wenn ich das selbst nicht finde.

    Ich habe übrigens eben mal zur letzten Maßnahme gegriffen: Neustart. Bringt nichts.
    if (!exit(-1)) fprintf(stderr, "exit call failed. Program will continue\n");
  • Ja, ich weiß...

    Die Sache ist die: ich starte das ganze nicht explizit in einem eigenen Thread. Aber das, wo der Aufruf herkommt habe ich gerade auf Threading umgestellt...

    Kleine Ursache, große Wirkung.
    if (!exit(-1)) fprintf(stderr, "exit call failed. Program will continue\n");
  • Original von kressevadder
    Mal ungeachtet der Tatsache, daß das normalerweise funktioniert: Was soll dieses

    forkThreadForFunction ()

    NSURLConnection läuft doch IMHO nicht in einem eigenen Thread.

    Und wenn du mal nach _pthread_body googlest findest du jede Menge Hilferufe von Leuten, denen iTunes oder sonst was beim Update abrauscht...


    Verstehe ich nicht. Tom versucht mir auch schon seit Tagen zu erklären, warum ich bei NSURLConnection keine Threads verwenden muss ... es geht nicht in meine Hirse rein. 8o