CardDAV with osX/iPhone clients - iphone

I am implementing a CardDAV backend to a crm package.
During the handshake with my backend the following request/response is handled:
PROPFIND /directory/ HTTP/1.1
Host: 10.0.0.202:9292
User-Agent: Address%20Book/883 CFNetwork/454.11.12 Darwin/10.7.0 (i386) (MacBookPro4%2C1)
Content-Type: text/xml; charset=utf-8
Depth: 0
Accept: */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Content-Length: 147
Connection: keep-alive
<?xml version="1.0" encoding="utf-8"?>
<D:propfind xmlns:D="DAV:" xmlns:C="DAV:">
<D:prop>
<C:current-user-privilege-set/>
</D:prop>
</D:propfind>
HTTP/1.1 207
Content-Type: text/xml; charset="utf-8"
Content-Length: 432
Connection: keep-alive
Server: thin 1.2.11 codename Bat-Shit Crazy
<?xml version="1.0" encoding="UTF-8"?>
<D:multistatus xmlns:D="DAV:">
<D:response>
<D:href>http://10.0.0.202:9292/directory/</D:href>
<D:propstat>
<D:prop>
<D:current-user-privilege-set>
<D:privilege>
<D:read/>
</D:privilege>
</D:current-user-privilege-set>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
</D:multistatus>
PROPFIND /contacts/ HTTP/1.1
Host: 10.0.0.202:9292
User-Agent: Address%20Book/883 CFNetwork/454.11.12 Darwin/10.7.0 (i386) (MacBookPro4%2C1)
Content-Type: text/xml; charset=utf-8
Depth: 0
Accept: */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Content-Length: 167
Connection: keep-alive
<?xml version="1.0" encoding="utf-8"?>
<D:propfind xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:carddav">
<D:prop>
<C:addressbook-home-set/>
</D:prop>
</D:propfind>
HTTP/1.1 207
Content-Type: text/xml; charset="utf-8"
Content-Length: 408
Connection: keep-alive
Server: thin 1.2.11 codename Bat-Shit Crazy
<?xml version="1.0" encoding="UTF-8"?>
<D:multistatus xmlns:D="DAV:">
<D:response>
<D:href>http://10.0.0.202:9292/contacts/</D:href>
<D:propstat>
<D:prop>
<D:addressbook-home-set>
<D:href>http://10.0.0.202:9292/contacts/</D:href>
</D:addressbook-home-set>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
</D:multistatus>
This is despite my CardDAV backend never hinting that /directory/ is anything that the client need concern itself with.
The client is returning the error The CardDAV server returned an error (207) for the user "richo", however when I patched the server to return a different status code (200) I got the same error, but with a new status code.
I am working on the hunch that something else is upsetting it about the response. I have tried returning absolute instead of relative URL's (and vice versa) to no avail.
Any input appreciated. There is a similar issue on the mac forums here that seems to end with resolution but the links are broken.

As it turned out, it was a namespace issue.
using the urn:ietf:params:xml:ns:carddav namespace where appropriate cleared it up.

Related

Fiddler doesn't capture SOAP Action

How do we find the SOAP action in fiddler:-
I captured the text view of the request. It doesn't show the request SOAP action:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Header><a:Security soap:mustUnderstand="1" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><a:UsernameToken wsu:Id="UsernameToken-1" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><a:Username>LP_DEALIO#SERVICES</a:Username><a:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">Abc.1234</a:Password></a:UsernameToken></a:Security></s:Header><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Get__CompIntfc__LP_PC_PROJECT_GEN xmlns="http://xmlns.oracle.com/Enterprise/Tools/schemas/M676402.V1"><BUSINESS_UNIT>US001</BUSINESS_UNIT><PROJECT_ID>LM202017</PROJECT_ID></Get__CompIntfc__LP_PC_PROJECT_GEN></s:Body></s:Envelope>
The SOAP Action is found in the Headers Section in Fiddler. Something like this:-
POST /PSIGW/PeopleSoftServiceListeningConnector/PSFT_EP/CI_LP_PC_PROJECT_GEN.1.wsdl HTTP/1.1
Content-Type: text/xml; charset=utf-8
VsDebuggerCausalityData: uIDPo+YluAuf3g9BhNp2nGC57WUAAAAA60+5s/MerUGZDfyhBXBAgPyLh3Vk3hZMrWvRTb0KntcACQAA
SOAPAction: "CI_LP_PC_PROJECT_GEN_UP.V1"
Host: psf92extigw.am.jll.com
Content-Length: 1039
Expect: 100-continue
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

JasperReport Server REST 2 api - Creating a new report

I was not able to find any api that can actually create a report on the JasperReports Server.
There is one to create resource.
http://community.jaspersoft.com/documentation/jasperreports-server-web-services-guide/v550/creating-resource
To an extend it tells about how to create a folder etc. but talks nothing about creating a report in all.
Any idea on how a report (jrxml) can be done in a programmatic way?
Thanks.
To post your reports manually to the JasperServer repository, use the same method as in the link you posted, but you aren't posting a resourceDescriptor. You should be posting a reportUnit instead.
Here is an example of the PUT command where I'm sending a (gzipped) jrxml file I named TestJrxmlFile to the repository creating a new report:
PUT http://localhost:8080/jasperserver-pro/rest_v2/resources/public/TestJrxmlFile?createFolders=true&overwrite=true HTTP/1.1
Content-Type: application/repository.reportUnit+xml
User-Agent: Jersey/2.13 (Apache HttpClient 4.3.4)
Transfer-Encoding: chunked
Host: localhost:8080
Connection: Keep-Alive
Cookie: JSESSIONID=45F47838C567120CF4DB1068AE0473C4; userLocale=en_US
Cookie2: $Version=1
Accept-Encoding: gzip,deflate
82d
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><reportUnit><description>ds</description><label>TestJrxmlFile</label><permissionMask>1</permissionMask><uri>/public/TestJrxmlFile</uri><version>-1</version><alwaysPromptControls>true</alwaysPromptControls><controlsLayout>popupScreen</controlsLayout><resources/><inputControls/><jrxmlFile><label>Main jrxml</label><permissionMask>1</permissionMask><uri>/public/TestJrxmlFile_files/main_jrxml</uri><version>-1</version><content>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCEtLSBDcmVhdGVkIHdpdGggSmFzcGVyc29mdCBTdHVkaW8gdmVyc2lvbiA2LjEuMC5maW5hbCB1c2luZyBKYXNwZXJSZXBvcnRzIExpYnJhcnkgdmVyc2lvbiA2LjEuMCAgLS0+CjwhLS0gMjAxNS0xMS0xM1QwOTo1OTo1MiAtLT4KPGphc3BlclJlcG9ydCB4bWxucz0iaHR0cDovL2phc3BlcnJlcG9ydHMuc291cmNlZm9yZ2UubmV0L2phc3BlcnJlcG9ydHMiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL2phc3BlcnJlcG9ydHMuc291cmNlZm9yZ2UubmV0L2phc3BlcnJlcG9ydHMgaHR0cDovL2phc3BlcnJlcG9ydHMuc291cmNlZm9yZ2UubmV0L3hzZC9qYXNwZXJyZXBvcnQueHNkIiBuYW1lPSJCbGFua19BNCIgcGFnZVdpZHRoPSI1OTUiIHBhZ2VIZWlnaHQ9Ijg0MiIgY29sdW1uV2lkdGg9IjU1NSIgbGVmdE1hcmdpbj0iMjAiIHJpZ2h0TWFyZ2luPSIyMCIgdG9wTWFyZ2luPSIyMCIgYm90dG9tTWFyZ2luPSIyMCIgdXVpZD0iOTlmNDQzNzAtY2FjNi00YWVkLTgyMDUtMDdkMThmZDUwNmJmIj4KCTxxdWVyeVN0cmluZz4KCQk8IVtDREFUQVtdXT4KCTwvcXVlcnlTdHJpbmc+Cgk8YmFja2dyb3VuZD4KCQk8YmFuZCBzcGxpdFR5cGU9IlN0cmV0Y2giLz4KCTwvYmFja2dyb3VuZD4KCTx0aXRsZT4KCQk8YmFuZCBoZWlnaHQ9Ijc5IiBzcGxpdFR5cGU9IlN0cmV0Y2giLz4KCTwvdGl0bGU+Cgk8cGFnZUhlYWRlcj4KCQk8YmFuZCBoZWlnaHQ9IjM1IiBzcGxpdFR5cGU9IlN0cmV0Y2giLz4KCTwvcGFnZUhlYWRlcj4KCTxjb2x1bW5IZWFkZXI+CgkJPGJhbmQgaGVpZ2h0PSI2MSIgc3BsaXRUeXBlPSJTdHJldGNoIi8+Cgk8L2NvbHVtbkhlYWRlcj4KCTxkZXRhaWw+CgkJPGJhbmQgaGVpZ2h0PSIxMjUiIHNwbGl0VHlwZT0iU3RyZXRjaCIvPgoJPC9kZXRhaWw+Cgk8Y29sdW1uRm9vdGVyPgoJCTxiYW5kIGhlaWdodD0iNDUiIHNwbGl0VHlwZT0iU3RyZXRjaCIvPgoJPC9jb2x1bW5Gb290ZXI+Cgk8cGFnZUZvb3Rlcj4KCQk8YmFuZCBoZWlnaHQ9IjU0IiBzcGxpdFR5cGU9IlN0cmV0 Y2giLz4KCTwvcGFnZUZvb3Rlcj4KCTxzdW1tYXJ5PgoJCTxiYW5kIGhlaWdodD0iNDIiIHNwbGl0VHlwZT0iU3RyZXRjaCIvPgoJPC9zdW1tYXJ5Pgo8L2phc3BlclJlcG9ydD4K
35
</content><type>jrxml</type></jrxmlFile></reportUnit>
0
Updating a single jrxml file would require posting a file a la
PUT http://localhost:8080/jasperserver-pro/rest_v2/resources/public/TestJrxmlFile_files/main_jrxml?createFolders=true&overwrite=true HTTP/1.1
Content-Type: application/repository.file+xml
User-Agent: Jersey/2.13 (Apache HttpClient 4.3.4)
Transfer-Encoding: chunked
Host: localhost:8080
Connection: Keep-Alive
Cookie: JSESSIONID=CBE64F76548FC2D4CB73281A6FEB9319; userLocale=en_US
Cookie2: $Version=1
Accept-Encoding: gzip,deflate
93a
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><file><creationDate>2015-11-13T09:59:55</creationDate><label>Main jrxml</label><permissionMask>1</permissionMask><updateDate>2015-11-13T09:59:55</updateDate><uri>/public/TestJrxmlFile_files/main_jrxml</uri><version>0</version><content>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCEtLSBDcmVhdGVkIHdpdGggSmFzcGVyc29mdCBTdHVkaW8gdmVyc2lvbiA2LjEuMC5maW5hbCB1c2luZyBKYXNwZXJSZXBvcnRzIExpYnJhcnkgdmVyc2lvbiA2LjEuMCAgLS0+CjwhLS0gMjAxNS0xMS0xM1QxMDoxMjowNiAtLT4KPGphc3BlclJlcG9ydCB4bWxucz0iaHR0cDovL2phc3BlcnJlcG9ydHMuc291cmNlZm9yZ2UubmV0L2phc3BlcnJlcG9ydHMiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL2phc3BlcnJlcG9ydHMuc291cmNlZm9yZ2UubmV0L2phc3BlcnJlcG9ydHMgaHR0cDovL2phc3BlcnJlcG9ydHMuc291cmNlZm9yZ2UubmV0L3hzZC9qYXNwZXJyZXBvcnQueHNkIiBuYW1lPSJCbGFua19BNCIgcGFnZVdpZHRoPSI1OTUiIHBhZ2VIZWlnaHQ9Ijg0MiIgY29sdW1uV2lkdGg9IjU1NSIgbGVmdE1hcmdpbj0iMjAiIHJpZ2h0TWFyZ2luPSIyMCIgdG9wTWFyZ2luPSIyMCIgYm90dG9tTWFyZ2luPSIyMCIgdXVpZD0iOTlmNDQzNzAtY2FjNi00YWVkLTgyMDUtMDdkMThmZDUwNmJmIj4KCTxwcm9wZXJ0eSBuYW1lPSJpcmVwb3J0Lmphc3BlcnNlcnZlci51cmwiIHZhbHVlPSJodHRwOi8vbG9jYWxob3N0OjgwODAvamFzcGVyc2VydmVyLXByby8iLz4KCTxwcm9wZXJ0eSBuYW1lPSJpcmVwb3J0Lmphc3BlcnNlcnZlci51c2VyIiB2YWx1ZT0iamFzcGVyYWRtaW4iLz4KCTxwcm9wZXJ0eSBuYW1lPSJpcmVwb3J0Lmphc3BlcnNlcnZlci5yZXBvcnQucmVzb3VyY2UiIHZhbHVlPSIvcHVibGljL1Rlc3RKcnhtbEZpbGVfZmlsZXMvbWFpbl9qcnhtbCIvPgoJPHByb3BlcnR5IG5hbWU9ImlyZXBvcnQuamFzcGVyc2VydmVyLnJlcG9ydFVuaXQiIHZhbHVlPSIvcHVibGljL1Rlc3RKcnhtbEZpbGUiLz4KCTxxdWVyeVN0cmluZz4KCQk8IVtDREFUQVtdXT4KCTwvcXVlcnlTdHJpbmc+Cgk8YmFja2dyb3VuZD4KCQk8YmFuZCBzcGxpdFR5cGU9IlN0cmV0Y2giLz4KCTwvYmFja2dyb3VuZD4KCTx0aXRsZT4KCQk8YmFuZCBoZWlnaHQ9Ijc5IiBzcGxpdFR5cGU9IlN0cmV0Y2giLz4KCTwvdGl0bGU+Cgk8cGFnZUhlYWRlcj4KCQk8YmFuZCBoZWlnaHQ9IjM1IiBzcGxpdFR5cGU9IlN0cmV0Y2giLz4KCTwvcGFnZUhlYWRlcj4KCTxjb2x1bW5IZWFkZXI+CgkJPGJhbmQgaGVpZ2h0PSI2MSIgc3BsaXRUeXBlPSJTdHJldGNoIi8+Cgk8L2NvbHVtbkhlYWRlcj4KCTxkZXRhaWw+CgkJPGJhbmQgaGVpZ2h0PSIxMjUiIHNwbGl0VHlwZT0iU3RyZXRjaCIvPgoJPC9kZXRhaWw+Cgk8Y29sdW1uRm9vdGVyPgoJCTxiYW5kIGhlaWdodD0iNDUiIHNwbGl0VHlwZT0iU3RyZXRjaCIvPgoJPC9jb2x1bW5Gb290ZXI+Cgk8cGFnZUZvb3Rlcj4KCQk8YmFuZCBoZWlnaHQ9IjU0IiBzcGxpdFR5cGU9IlN0cmV0Y2giLz4KCTwvcGFnZUZvb3Rlcj4KCTxzdW1tYXJ5PgoJCTxiYW5kIGhlaW dodD0iNDIiIHNwbGl0VHlwZT0iU3RyZXRjaCIvPgoJPC9zdW1tYXJ5Pgo8L2phc3BlclJlcG9ydD4K
23
</content><type>jrxml</type></file>
0

Server does not accept my multipart/form-data

I try to upload an image to my webservice from my iphone application. The webservice is programmed in php. I have to send the image along with a device_id as multipart/form-data.
Something is wrong with my request because the server does not accept my device_id (invalid format). I am 100% positive that the device_id is correct because it works with my other requests.
I think there is something wrong with my request structure because Charles proxy cannot decode the multipart form-data.
Here is my request (sniffed with charles proxy):
POST /api/profile/update HTTP/1.1
Host: THE_URL
User-Agent: SeduceMe/1.0 CFNetwork/548.0.3 Darwin/11.2.0
Content-Length: 6639
Accept: */*
Content-Type: multipart/form-data; boundary=---------------------------255141413922088
Accept-Language: de-de
Accept-Encoding: gzip, deflate
Cookie: PHPSESSID=tlcpnqugcpgs0skh3l2ip9ujh7
Connection: keep-alive
Proxy-Connection: keep-alive
---------------------------255141413922088
Content-Disposition: form-data; name="device_id"
mgs2AHyvfIcSXHSKE+0eHA==
---------------------------255141413922088
Content-Disposition: form-data; name="form[file]"; filename="avatar.jpg"
Content-Type: image/jpeg
RAW_JPEG_DATA
---------------------------255141413922088--
there is a great wrapper to post form/data. it is ASIHTTPRequest
please look at ASIFormData
thanks/

Fiddler not capturing WCF traffic from the web server to the application server

I have two possible flows:
ConsoleClient -(1)-> ApplicationServer
or
SilverlightClient -(2)-> WebServer -(3)-> ApplicationServer
Fiddler successfully captures the HTTP traffic on the (1) and the (2), but not on the (3). Here is a sample capture on (1):
POST /WcfDemo/ws HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8
Host: il-mark-lt
Content-Length: 521
Expect: 100-continue
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><a:Action s:mustUnderstand="1">http://tempuri.org/IWcfDemoService/Add</a:Action><a:MessageID>urn:uuid:d7fde351-12fd-4872-bc26-52ff97f126e9</a:MessageID><a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand="1">http://il-mark-lt/WcfDemo/ws</a:To></s:Header><s:Body><Add xmlns="http://tempuri.org/"><x>4</x><y>5</y></Add></s:Body></s:Envelope>
HTTP/1.1 200 OK
Content-Length: 399
Content-Type: application/soap+xml; charset=utf-8
Server: Microsoft-HTTPAPI/2.0
Date: Sat, 17 Sep 2011 20:57:16 GMT
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><a:Action s:mustUnderstand="1">http://tempuri.org/IWcfDemoService/AddResponse</a:Action><a:RelatesTo>urn:uuid:d7fde351-12fd-4872-bc26-52ff97f126e9</a:RelatesTo></s:Header><s:Body><AddResponse xmlns="http://tempuri.org/"><AddResult>9</AddResult></AddResponse></s:Body></s:Envelope>
And here is an example of (2):
POST /WcfDemoService.svc/ws HTTP/1.1
Host: localhost:56970
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,application/json
Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.6,he-IL;q=0.5,he;q=0.4,ru-RU;q=0.3,ru;q=0.1
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://localhost:56970/ClientBin/SilverlightClient.xap
Content-Length: 581
Content-Type: application/soap+xml; charset=utf-8
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Header><a:Action s:mustUnderstand="1">http://tempuri.org/IWcfDemoService2/Add</a:Action><a:MessageID>urn:uuid:e8420d3e-f568-49ce-bfc7-5631d5bf3fd0</a:MessageID><a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand="1">http://localhost:56970/WcfDemoService.svc/ws</a:To></s:Header><s:Body><Add xmlns="http://tempuri.org/"><x>11</x><y>22</y><serverChannelKind>ws</serverChannelKind></Add></s:Body></s:Envelope>
HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Sat, 17 Sep 2011 20:59:23 GMT
X-AspNet-Version: 4.0.30319
Content-Length: 401
Cache-Control: private
Content-Type: application/soap+xml; charset=utf-8
Connection: Close
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><a:Action s:mustUnderstand="1">http://tempuri.org/IWcfDemoService2/AddResponse</a:Action><a:RelatesTo>urn:uuid:e8420d3e-f568-49ce-bfc7-5631d5bf3fd0</a:RelatesTo></s:Header><s:Body><AddResponse xmlns="http://tempuri.org/"><AddResult>33</AddResult></AddResponse></s:Body></s:Envelope>
Now, I am absolutely sure the (3) does get through. So, it all boils down to some misconfiguration on the WebServer, but I cannot nail it. The Web server is just a trivial ASP.NET application hosted within IIS. It even has the following lines in the web.config:
<system.net>
<defaultProxy>
<proxy bypassonlocal="false" usesystemdefault="true" />
</defaultProxy>
</system.net>
Still, this does not work.
To further strengthen my suspicion on the web server configuration, I have checked the SilverlightClient --> ApplicationServer flow and it is captured just fine.
I am using the Asp.Net development server.
Edit
Running procmon reveals that the following suspicious registry key is consulted (amongst others):
HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\ProxyBypass
And on my machine it was set to 1. I have changed it to 0 and seems like it solved my issue. The only problem is that when I change it back to 1 Fiddler continues to capture the problematic leg! Very interesting.
Anyway, I am satisfied, for now.
You are calling "localhost" right?
Fiddler is not able to capture the local traffic if you are using "localhost" as hostname.
Solutions:
Use servername (e.g. myserver)
Use ip4.fiddler (e.g. http://ipv4.fiddler:8787)
Not sure if these are causing it ... but,
A few things to check:
In IIS7 the appPool has a loadUserProfile setting. It causes the session to load a user profile which means it can get system proxy settings.
Check the code making the request from the webServer - even if you configure to use the system proxy and bypass onLocal (which only applies to names without dots in it), code making the request can still explicitly set to use or not to use a proxy.
Far fetched but you may want to play with the account the appPool runs as - local account with profile vs. Network Service.
Hope that helps - these network things have a lot of variables between two points :)

Unable to assemble multipart/form-data request

I'm trying to implement file upload functionality in the iPhone app. Server code is tested and works when files are uploaded from the desktop browser, so I moved to implementing the Objective-C client code. I'm assembling HTTP requests body manually, and despite that it looks correct, it is rejected by the server (server handler unable to extract the parts from multipart content). In desperation I've simplified the form to having only one parameter, but it still does not work.
I've captured the network traffic and I could see that Wireshark could not parse my multipart content as well (have a look at screenshots: Firefox request, iPhone request). I'm pasting it below in hope that you could see the errors I can't see.
Thanks in advance.
Firefox:
POST /cubepaint/actions/gallery/post HTTP/1.1
Host: [...]
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-GB; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Authorization: Basic [...]
Content-Type: multipart/form-data; boundary=---------------------------20072377098235644401115438165
Content-Length: 180
-----------------------------20072377098235644401115438165
Content-Disposition: form-data; name="deviceId"
12345
-----------------------------20072377098235644401115438165--
HTTP/1.1 200 OK
Date: Sat, 17 Oct 2009 22:09:21 GMT
Server: Apache/2.2.3 (Debian) DAV/2 SVN/1.4.2 mod_python/3.2.10 Python/2.4.4 mod_ssl/2.2.3 OpenSSL/0.9.8c
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
iPhone:
POST /cubepaint/actions/gallery/post HTTP/1.1
Host: [...]
User-Agent: Copenhagen/1.0 CFNetwork/459 Darwin/9.8.0
Content-Type: multipart/form-data; boundary=----------0E7B16E6-CD3D-4213-9B42-07DA30822C74
Accept: */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Authorization: Basic [...]
Content-Length: 187
Connection: keep-alive
----------0E7B16E6-CD3D-4213-9B42-07DA30822C74
Content-Disposition: form-data; name="deviceId"
00000000-0000-1000-8000-0016CBCC0B61
----------0E7B16E6-CD3D-4213-9B42-07DA30822C74--
HTTP/1.1 200 OK
Date: Sat, 17 Oct 2009 22:04:07 GMT
Server: Apache/2.2.3 (Debian) DAV/2 SVN/1.4.2 mod_python/3.2.10 Python/2.4.4 mod_ssl/2.2.3 OpenSSL/0.9.8c
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
Your iPhone version indicates keep-alive but doesn't specify a length. Not sure that's enough to cause trouble.
Also, is it possible your server is checking for user-agent strings it recognizes (say, for backward-compatibility mode)?
I'd also compare the two in a text editor that shows CR/LF characters to make sure you're getting proper line endings.
Another thing you could try is create a simple web-page that does a multipart POST and run it from the iPhone browser (instead of the Mac one) then check the headers that go across the wire. Or you could snag a toolkit like ASIHTTPRequest and see what kind of output it generates for multi-part posts (or just use the toolkit instead of trying to write your own).
Good luck
Solved by reading RFC 2046 (MIME specification): boundary between parts of multipart message should contain two leading '-'s, and last boundary should additionally contain two trailing '-'s. The boundary in the request header and request body in the Firefox request differ:
---------------------------20072377098235644401115438165
and
-----------------------------20072377098235644401115438165
The last boundary looks like this:
-----------------------------20072377098235644401115438165--
You really could not see this with the eye when there are so many leading '-'s in the original boundary.