AGSAttachmentManager does not properly handle secured services?

Discussion created by eddof13 on Sep 22, 2011
Latest reply on Oct 26, 2012 by njarecha-esristaff

I am having a problem using AGSAttachmentManager with a secured service (it works unsecured), specifically, with the adding of attachments.

Calling the following code on a secured service works fine when deleting attachments (the secured service works fine in general except for attachments):
AGSAttachmentManager *attMgr = [featureLayer attachmentManagerForFeature:graphic];
attMgr.delegate = self;

if ([attMgr hasLocalEdits]) {
[attMgr postLocalEditsToServer];

But when adding those attachments I get the following upon calling postLocalEditsToServer:

0. The error is EXC_BAD_ACCESS
1. It never makes it to attachmentManager:didPostLocalEditsToServer:
2. The following JSON data shows up in shouldProcessResultDataInBackground (when I use a category to override the function and print out the data), which leads me to believe it is not detecting a secured attachment service properly:
{"error":{"code":499,"message":"Unauthorised access","details":[]}}

3. Similar with item 2. above, looking through the debugger, inspecting the _requiresAuthentication variable after the crash shows (BOOL) NO, which is odd since the service is secured.
4. Here is the disassembly but it doesn't look that useful to me...?
//URLREQUEST::initialize(URLRequest const*, unsigned char)

0x357335a8  <+0000>  push {r4, r5, r6, r7, lr}
0x357335aa  <+0002>  add r7, sp, #12
0x357335ac  <+0004>  stmdb sp!, {r8, r10}
0x357335b0  <+0008>  uxtb r2, r2
0x357335b2  <+0010>  mov r5, r1
0x357335b4  <+0012>  mov r1, r2
0x357335b6  <+0014>  mov r4, r0
0x357335b8  <+0016>  bl 0x35732890 <_ZN10URLRequest20commonInitializationEh>
0x357335bc  <+0020>  cmp r0, #0
0x357335be  <+0022>  beq.n 0x3573368e <_ZN10URLRequest10initializeEPKS_h+230>
0x357335c0  <+0024>  ldr r0, [r5, #8]
0x357335c2  <+0026>  cbz r0, 0x357335c8 <_ZN10URLRequest10initializeEPKS_h+32>
0x357335c4  <+0028>  blx 0x357e2d5c <dyld_stub_CFURLCopyAbsoluteURL>
0x357335c8  <+0032>  ldrb.w r3, [r4, #40]
0x357335cc  <+0036>  str r0, [r4, #8]
0x357335ce  <+0038>  mov r0, r5
0x357335d0  <+0040>  orr.w r3, r3, #1 ; 0x1
0x357335d4  <+0044>  strb.w r3, [r4, #40]
0x357335d8  <+0048>  ldr r3, [r5, #12]
0x357335da  <+0050>  str r3, [r4, #12]
0x357335dc  <+0052>  bl 0x35735a60 <_ZNK10URLRequest19hasBodyOrBodyStreamEv>
0x357335e0  <+0056>  cmp r0, #0
0x357335e2  <+0058>  beq.n 0x35733684 <_ZN10URLRequest10initializeEPKS_h+220>
0x357335e4  <+0060>  vldr d6, [pc, #172] ; 0x35733694 <_ZN10URLRequest10initializeEPKS_h+236>
0x357335e8  <+0064>  vldr d7, [r5, #16]
0x357335ec  <+0068>  fcmpd d7, d6
0x357335f0  <+0072>  fmstat
0x357335f4  <+0076>  bpl.n 0x35733688 <_ZN10URLRequest10initializeEPKS_h+224>
0x357335f6  <+0078>  vmov r2, r3, d6
0x357335fa  <+0082>  ldr r0, [r5, #24]
0x357335fc  <+0084>  str r2, [r4, #16]
0x357335fe  <+0086>  str r3, [r4, #20]
0x35733600  <+0088>  cbz r0, 0x35733606 <_ZN10URLRequest10initializeEPKS_h+94>
0x35733602  <+0090>  blx 0x357e272c <dyld_stub_CFRetain>
0x35733606  <+0094>  ldr r6, [r5, #28]
0x35733608  <+0096>  str r0, [r4, #24]
0x3573360a  <+0098>  cbz r6, 0x3573361e <_ZN10URLRequest10initializeEPKS_h+118>
0x3573360c  <+0100>  sub.w r0, r4, #8 ; 0x8
0x35733610  <+0104>  blx 0x357e244c <dyld_stub_CFGetAllocator>
0x35733614  <+0108>  movs r1, #0
0x35733616  <+0110>  mov r2, r6
0x35733618  <+0112>  blx 0x357e235c <dyld_stub_CFDictionaryCreateMutableCopy>
0x3573361c  <+0116>  str r0, [r4, #28]
0x3573361e  <+0118>  ldrb.w r3, [r5, #40]
0x35733622  <+0122>  ldr r0, [r5, #32]
0x35733624  <+0124>  strb.w r3, [r4, #40]
0x35733628  <+0128>  cbz r0, 0x3573362e <_ZN10URLRequest10initializeEPKS_h+134>
0x3573362a  <+0130>  blx 0x357e272c <dyld_stub_CFRetain>
0x3573362e  <+0134>  str r0, [r4, #32]
0x35733630  <+0136>  ldr r0, [r5, #44]
0x35733632  <+0138>  cbz r0, 0x35733638 <_ZN10URLRequest10initializeEPKS_h+144>
0x35733634  <+0140>  blx 0x357e272c <dyld_stub_CFRetain>
0x35733638  <+0144>  str r0, [r4, #44]
0x3573363a  <+0146>  ldr r0, [r5, #52]
0x3573363c  <+0148>  cbz r0, 0x35733642 <_ZN10URLRequest10initializeEPKS_h+154>
0x3573363e  <+0150>  blx 0x357e272c <dyld_stub_CFRetain>
0x35733642  <+0154>  ldr r3, [r4, #36]
0x35733644  <+0156>  str r0, [r4, #52]
0x35733646  <+0158>  cbz r3, 0x3573364e <_ZN10URLRequest10initializeEPKS_h+166>
0x35733648  <+0160>  movs r0, #82
0x3573364a  <+0162>  bl 0x357d1624 <_Z21_coreLogInternalErrori>
0x3573364e  <+0166>  ldr r3, [r5, #36]
0x35733650  <+0168>  cbz r3, 0x3573367c <_ZN10URLRequest10initializeEPKS_h+212>
0x35733652  <+0170>  sub.w r6, r4, #8 ; 0x8
0x35733656  <+0174>  mov r0, r6
0x35733658  <+0176>  blx 0x357e244c <dyld_stub_CFGetAllocator>
0x3573365c  <+0180>  ldr.w r10, [r5, #36]
0x35733660  <+0184>  mov r8, r0
0x35733662  <+0186>  mov r0, r6
0x35733664  <+0188>  blx 0x357e244c <dyld_stub_CFGetAllocator>
0x35733668  <+0192>  mov r1, r0
0x3573366a  <+0194>  movs r0, #40
0x3573366c  <+0196>  bl 0x35732a24 <_ZN17CFAllocatedObjectnwEmPK13__CFAllocator>
0x35733670  <+0200>  mov r1, r8
0x35733672  <+0202>  mov r2, r10
0x35733674  <+0204>  mov r6, r0
0x35733676  <+0206>  bl 0x3573369c <_ZN11HTTPRequestC1EPK13__CFAllocatorPKS_>
0x3573367a  <+0210>  str r6, [r4, #36]
0x3573367c  <+0212>  ldr r0, [r5, #64]
0x3573367e  <+0214>  str r0, [r4, #64]
0x35733680  <+0216>  movs r0, #1
0x35733682  <+0218>  b.n 0x3573368e <_ZN10URLRequest10initializeEPKS_h+230>
0x35733684  <+0220>  vldr d7, [r5, #16]
0x35733688  <+0224>  vmov r2, r3, d7
0x3573368c  <+0228>  b.n 0x357335fa <_ZN10URLRequest10initializeEPKS_h+82>
0x3573368e  <+0230>  ldmia.w sp!, {r8, r10}
0x35733692  <+0234>  pop {r4, r5, r6, r7, pc}
0x35733694  <+0236>  lsls r0, r0, #0
0x35733696  <+0238>  lsls r0, r0, #0
0x35733698  <+0240>  lsls r0, r0, #0
0x3573369a  <+0242>  eors r6, r5

//[NSURLConnection initWithRequest:delegate:]

0x3453e7f0  <+0000>  push {r4, r5, r7, lr}
0x3453e7f2  <+0002>  add r7, sp, #8
0x3453e7f4  <+0004>  sub sp, #20
0x3453e7f6  <+0006>  ldr r1, [pc, #44] (0x3453e824 <-[NSURLConnection initWithRequest:delegate:]+52>)
0x3453e7f8  <+0008>  mov.w r12, #1 ; 0x1
0x3453e7fc  <+0012>  movs r4, #0
0x3453e7fe  <+0014>  add r1, pc
0x3453e800  <+0016>  str.w r12, [sp]
0x3453e804  <+0020>  ldr r1, [r1, #0]
0x3453e806  <+0022>  movs r5, #0
0x3453e808  <+0024>  str.w r12, [sp, #12]
0x3453e80c  <+0028>  str r4, [sp, #4]
0x3453e80e  <+0030>  str r5, [sp, #8]
0x3453e810  <+0032>  add.w r12, r12, #4294967295 ; 0xffffffff
0x3453e814  <+0036>  str.w r12, [sp, #16]
0x3453e818  <+0040>  blx 0x34612df8 <dyld_stub_objc_msgSend>
0x3453e81c  <+0044>  sub.w sp, r7, #8 ; 0x8
0x3453e820  <+0048>  pop {r4, r5, r7, pc}
0x3453e822  <+0050>  nop
0x3453e824  <+0052>  stmia r5!, {r1, r4, r5, r6}
0x3453e826  <+0054>  lsrs r4, r3, #8

I think a quick fix (for me at least) would be to override the _requiresAuthentication ivar, but sadly it is defined as @private.

I tried doing the following to just append a token when its adding attachments, and it no longer crashes
@implementation AGSJSONRequestOperation (MyOverride)

- (id)initWithRequest:(NSURLRequest *)req {
    if ([[req.URL absoluteString] rangeOfString:@"addAttachment"].location == NSNotFound) {
        self = [super initWithRequest:req];
    else {
        self = [super initWithRequest:
                [NSURLRequest requestWithURL:
                 [NSURL URLWithString:
                  [NSString stringWithFormat:@"%@?token=%@", [req.URL absoluteString], @"MYTOKEN"]]
                                 cachePolicy:req.cachePolicy timeoutInterval:req.timeoutInterval]];   
    return self;

- (BOOL)shouldProcessResultDataInBackground:(NSData *)data
    NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
    return [super shouldProcessResultDataInBackground:data];


it replaces the response data above with
<meta http-equiv="X-UA-Compatible" content="IE=7" />
  <title>ArcGIS Server REST API Login</title>
  <link href='/ArcGIS/rest/ESRI.ArcGIS.Rest.css' rel='stylesheet' type='text/css'>
<body onload="javascript:document.all.username.focus();">
<table width="100%" id="userTable">
<td id="titlecell">ArcGIS Services Directory</td>
<td align="right">
<a href="https://MYIP/ArcGIS/tokens/getToken.html" target="_blank">Get Token</a>
<table id="navTable" width="100%">
<tr valign="top">
<td id="breadcrumbs">
ArcGIS Server REST API Login</td>
<td align="right" id="help">
<div class='restBody'>
<form method="post">
<table id="loginTable">
<tr><td colspan="2"><b>Login</b></td></tr>
<td>User Name</td><td><input type="text" name="username" value="" /></td>
<td>Password</td><td><input type="password" name="password" /></td>
<td colspan="2"><input type="submit" value='Login' /></td>
<input type="hidden" name="redirect" value="MYSERVICENAMEHERE/FeatureServer/0/3671/addAttachment?token=TOKENHERE" />

and I just get some sort of error from the json-framework JSON parser in the backend in the attachmentManager:didPostLocalEditsToServer: results
Unrecognised leading character

Should this method with the hard coded token work, I still don't think this is a good solution.

Anyway, I'll probably just scrap the AGSAttachmentManager and push the attachments myself using the AGSFeatureLayer methods (which hopefully will not share the same problems) unless someone has an idea of what I'm doing wrong. Of course, if this is a bug then hopefully this report helps.