amazon S3 upload API is sensitive to http post parameter ordering - http

I've created a bucket where policy makes it mandatory to specify the content-type of the object being uploaded. If I specify the content-type after file element, (example below)
<form action="..">
...
<input type='file' name='file' />
<input name='content-type' value='image/jpeg' />
<input type='submit' />
</form>
it returns following error
<Error>
<Code>AccessDenied</Code>
<Message>Invalid according to Policy: Policy Condition failed: ["starts-with", "$Content-Type", ""]</Message>
<RequestId>15063EB427B4A469</RequestId>
<HostId>yEzAPF4Z2inaafhcqyQ4ooLVKdwnsrwqQhnYg6jm5hPQWSOLtPTuk0t9hn+zkBEbk+rP4S5Nfvs=</HostId>
</Error>
If I specify content-type before file element, upload works as expected. I encountered this behaviour for the first time. I have a few questions regarding it.
Is it part of some specification where clients and all intermediate proxies are supposed to maintain order of http post params? Please point me to it.
Why would you make your API be aware of such ordering? In this particular case I can guess that the file can be huge and unless you are seeing all expected params before, you should immediately return failure. Please correct me if my understanding is not correct.

It is part of the spec that the parts are sent as ordered in the form. There is no reason to believe that reordering by an intermediate proxy would be allowed.
The form data and boundaries (excluding the contents of the file) cannot exceed 20K.
...
The file or content must be the last field in the form.
http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTForms.html#sigv4-HTTPPOSTFormFields
The logical assumption is that this design allows S3 to reject invalid uploads early.

Related

chart.apis.google.com returns error 400

Yesterday I have run extensive DNS tests with namebench, since my current DNS server is giving me lots of problems. The problem is that all resulting Google Charts are failing to load. This never happened to me, though. I looked at the source for the HTML page returned by namebench, and opened the links for the graphs, and they return the HTTP error 400.
One sample URL:
http://chart.apis.google.com/chart?chxt=y%2Cx%2Cx&chd=e%3AEmE8FXFeFfFqFwFxFxFzF9GEGGGKGLGOGQGRGSGSGTGWGYGcGdGdGdGeGhGiGjGlGqGqGqGqGvGwGxGxG0G0G0G1G2G4G5G7G9G-G-HAHAHEHGHKHLHMHMHNHPHRHWHWHYHYHZHaHeHiHiHjHkHkHlHmHnHnHoHoHpHqHsHtHtHuHwHxHyHzHzH0H1H2H2H7H9H9H-H-H.H.IAIAIBIBICIDIEIGIHILINININIOIQIRIRISIWIWIZIaIdIdIhIiIiIlImInIoIqIqIsIsIwIyIyIzI0I0I4I4I8I9I.JBJBJBJCJCJCJCJGJGJHJJJKJMJPJRJSJUJUJXJXJYJYJZJaJbJdJdJeJfJgJgJnJoJpJpJpJqJsJsJtJuJvJvJxJzJ3J7J-J-J.KAKAKBKCKCKDKEKFKFKGKIKLKMKMKOKPKQKQKRKSKSKSKTKUKVKWKXKaKaKcKjKjKmKrKsKtKuKxKzKzK2K3K3K4K4K5K6K7LALALBLBLELFLGLHLILILMLOLPLRLVLVLaLaLdLeLjLpLpLrLsLvLxLzLzL1L4L4L6L6L8L-MBMBMBMCMGMHMIMJMJMLMUMWMaMcMcMcMgMiMiMmMoMqMvMyM2M2M5M7M8M8M-M.NANMNZNdNoNqNrN0N2OFOGOPOWOcOiOqO6O7PBPDPRPSPhPvPxQeQrQsRQRtSOSUSgTBTVTkUKU9VIWQYWY0ZRZsaNbPbYcEc8dkftmvpTtEuZ4d.7&chxp=0%7C2%2C1155&chxr=1%2C0%2C2570%7C2%2C-128.5%2C2698.5&chxtc=1%2C-720&chco=0000ff&chbh=a&chs=720x415&cht=bhg&chxl=0%3A%7CSuomi%204%20FI%7CDiveo%20MX%7CNetscalibur%20IT%7CTDA%20DZ%7CGlobecomm%20Systems%20A2%7C128.199.248.105%7C192.71.211.211%7CPokoeln%20DE%7C103.241.0.207%7CGaoland-2%20FR-2%7C41.185.78.25%7C103.25.56.238%7C84.200.83.161%7C163.47.20.30%7CFortressITX%20US%7C163.47.21.44%7C103.25.202.192%7CReynwood%20Comm%20US%7C151.236.20.236%7C295.ca-2%20CA-2%7C106.185.41.36%7CChristiania%20DK%7CGradwell-2%20GB%7C213.183.57.55%7Crdsar%20RO%7CIPLAN-2%20AR%7C192.71.218.218%7CTelefonica%20Centroamerica%20SV%7C192.71.247.247%7CAS520.net%20EU%7C178.17.170.67%7CFast%20GB%7CCETIC%20Algeria%20DZ%7COpole%20PL%7CGaoland-1%20FR%7CIsik%20Universitesi%20TR%7CBatelco-2%20JO%7CHamilton%20Hydro%20/%20FibreWired%20CA%7C88.82.109.9%7C31.220.5.106%7CMeganet%20US%7CnFrame-1%20US%7CRDSNet-2%20RO-2%7CGlobal%20Crossing%20snv%20US%7CDNS-Roots%20NYC%20US%7CUnifiedroot-2%20NL%7CCaucasus%20Online%20GE%7C217.78.6.191%7COceanic%20Cable%20US%7CFirmRadio%20UA%7CCodetel%20DO%7CUnifiedroot-1%20NL%7CRDS%20Pitesti%20RO%7CGlobalNet-2%20MT%7C8e6%20Technologies%20US%7CGibNet/Sapphire%20GI%7C151.236.29.92%7CUnifiedroot-6%20NL%7CGibnet/Sapphire-2%20GI%7CSunrise-3%20CH%7CCA-DNS/Verizon-2%20CA%7CVozTelecom%20ES%7CComput%20RU%7CInfoTelecom%20ES%7CSATCOM%20Systems%20A2%7Ceuroweb%20RO%7CInternap-2%20US%7C23.226.230.72%7CSloboda%20UA%7CPlant%20Telecom/InfoAve%204%20US%7CNeo%20ES%7C104.245.33.185%7CInFlow%20San%20Diego%20US%7CFrii-2%20US%7CDPN%20Duss%20DE%7CETB%20CO-3%7CMobtel%20Srbija%20SR%20RS%7C192.71.249.249%7C104.219.55.89%7C62.141.38.230%7CEUItalia%204%20IT%7CAmnet%20Honduras%20HN%7CEUItalia%203%20IT%7CStarnet%20MD%7CG-Tel%20Azteca%20MX%7CMkData%20SE%7CTtnet%2039%20TR%7CDiveo-2%20MX%7CRSSPNet%20RU%7CMiconet%20PL%7CNeterra%20BG%7CETB-2%20CO%7CMovistar-2%20ES%7Cbbsyd%20DK%7CTelusMobility%203%20CA%7CAll2Easy/Modesto%20US%7CHydro%20One%20CA%7C37.187.0.40%7CETB%20CO-2%7CTtnet%2040%20TR%7CADAM%20ES%7CUni-Ljubljana%20SI%7CPLD-2%20US%7C78.47.34.12%7CInfracom%20Network%20Application%20IT%7CCellNet%20BG%7CUltraVPN-2%20FR%7CMT-2%20MK%7CTelcel-1%20MX%7CAirbites%20Lviv-2%20UA%7CTelio-2%20NO%7CDTAG%20L%20DE%7CMaxcom%20MX%7C31.220.43.191%7CRadiant-2%20CA%7CIndigo%20IE%7CProfiber%20DK%7CETB%20CO%7CTelcel-2%20MX%7CBatelco-1%20JO%7C178.79.174.162%7CAPUA%20inet-2%20AG%7CBresnan-2%20US%7Clandsraad%20ES%7CaltoHiway-2%20GB%7CTNG-2%20DE%7CNavega-2%20GT%7CCable.net%20CO%7CUU%20EU%200702%20DE%7CZugernet%20CH%7CBHI-2%20US%7CCesnet%20CZ%7Cxtdnet%20NL%7CAmigo-2%20GT%7CDTAG%20H%20DE%7CBerlin%20CCC%20DE%7CEOL-2%20HU%7C108.61.210.58%7CUni%20Ulm%20DE%7CSWISP-2%20GB%7CWiBand%20CA%7CMindark%20SE%7CCyberus-3%20CA%7CAlharbitelecom%20GB%7CBright/Horizontel%20US%7CHurricane%20Electric%7CAvalonia%20DK%7C95.85.9.86%7CVTX%20Datacomm%20CH%7CUSB%20Skynet%20VE%7CByteCamp-2%20DE%7CMIPPS%20INC%20CA%7CKELCOM/Cybersurf-2%20CA%7CClearwire%20WAR%20US%7CKELCOM/Cybersurf%20CA%7CWIND-2%20IT%7CO2%20Ireland-2%20IE%7CNavega%20GT%7CSWISP%20GB%7CNTT%20EU%20GB%7C69.28.67.83%7CReflact%20DE%7CPLD%20US%7CNefarious%3F%20US%7CClara.net%20DE%7CBlueWin%20CH%7CDTAG-F%20DE%7CUU%20EU%200300%20FR%7CAvalonia-3%20DK%7CNumericable-2%20FR%7CGorgeNet-2%20US%7C104.245.39.112%7CWiTopia%20US%7CSprint%20PCS/brbnca-2%20US%7CTelefonica%20CentroAmerica%20GT%7CSATCOM%20Systems-2%20A2%7Cmtweb/transaria%20US%7CBT%20Alliance/INFONET%20US%7CBluewin%202%20CH%7CAEBC-4%20CA%7CInternap%20US%7CMonzoon%20ZRH-2%20CH%7CAvalonia-2%20DK%7CBluewin-4%20CH%7Calharbitelecom%20GB%7CBsoCom%20FR%7CSvenskaKyrkan%20SE%7COpalSolutions-3%20GB%7CCirque%20DK%7CUU%20EU%20206%7CIndigo%20IE-2%7CTital%20Internet%20GB%7CTime%20Warner%20TOSA-2%20US%7CPaeTec%20Ana-7%20US%7CSpeakeasy%20Seattle%20US%7CCSInet%20US%7CGreat%20Lakes%20Internet%20US%7CMultiband%20Corporation%20US%7CUU%20EU-3%20GB%7CColo4Dallas%20US%7CUU%20EU-201%20NL%7CHerakles%20Sacremento%20US%7CBestel-2%20MX%7CNetworkOnline%20US%7CUU%20EU%20400%7CUnited%20Online%20VGS%20US%7CSprint%20PCS%20Chi-2%20US%7CIntrinsec%20FR%7CEircom-2%20IE%7CTELUS%20Mobility-2%20CA%7CU.%20of%20British%20Columbia%20CA%7CUU%20EU%205a%20GB%7CCox-7%20US%7CRIO%20Networks%20US%7CAmigo%20GT%7CBHI%20US%7CFortalnet%20BR%7CSprint%20PCS%20brbncar12%20US%7CUUnet-EU4%20GB%7CUU%20EU%200703%20DE%7CAirband%20US%7CCityNet%203%20US%7CMonzoon%20CH%7CG-Tel%20Maya%20MX%7CGlobal%20Crossing%20Phoenix-2%20US%7CExceed%20Tech%20US%7CInternap%20Seattle-2%20US%7CInFlow%20ATL%20US%7CU%20of%20Houston-1%20US%7CTriad%20Telecom%20US%7CHorizon%20Cable%20Stinson-2%20US%7CPOBOX%20internet%20GB%7CCox-6%20US%7CO1%204%20US%7CVerizon%20Seattle%20US%7CDynGuide-2%7CPNAP-LON-2%20GB%7CSungard%20Inflow%20US%7CTELUS%20Mobility%20CA%7CACNUSA%7CEU%20BT%20AMS%20NL%7CGigaDNS%20BR%7CNeonova%20Network%20Services%20US%7CVerizon%20Dial-Up%20TX%20US%7CCA-DNS/Verizon%20CA%7CSYS-127.0.0.1%7CGEUS%7CExeculink%20CA%7C295.ca%20CA-2%7CInternap%20Seattle%20US%7CCyberNet%20Comm%20US%7CInterap%20LAX-2%20US%7CHydro%20One-2%20CA%7CUmich%20ITD-2%20US%7CVT%20ISB%20US%7CPrimary%20US%7CU.%20of%20Texas%20at%20San%20Antonio%20US%7CCox%20Oklahoma%20City-2%20US%7CInternap%20LAX%20US%7CMSU%20ATS%20US%7CSpeedNet%20Michigan%20US%7CSprintlink%7CSpirit%20Telecom%20US%7CSprint%20PCS/ekrg-2%20US%7CAPI%20Digital%20US%7CTelwest%20US%7CU%20of%20Houston-2%20US%7CPaeTec%20Chicago%20CA%7CInternap%20SJE%20US%7CVerizon%20NC%20Opt-Out%20US%7CSogetel-2%20CA%7CPathway%20CA%7CInternap%20Denver%20US%7CCybersurf%20CA%7CSprint%20PCS%20Ft.%20Worth%20US%7CEasytel%203%20US%7CSprint%20PCS/atlng%20US%7CDistributel-2%20CA%7CExeculink%20CA-2%7CUU%20Cache-6%20US%7CCable%20%26%20Wireless%20DE-3%7CISP%20Alliance%2C%20INC%20US%7CDnet-3%20US%7CDSL%20Extreme-2%20US%7CInternap%20ACS%20US%7CSBC/AT%26T%20Global-2%20US%7CPNAP%20London%20GB%7CUOL%20BR%7CVerizionBusiness%20US%7CInternap%20Houston%20US%7CCox%20Oklahoma%20City%20US%7CDSL%20Extreme-5%20US%7CSprint%20PCS%20Ft.%20Worth-2%20US%7CMCI-3%20US%7CFlow%20Jamaica-4%20JM%7CSecureDesigns-2%20US%7CDynGuide%7CUnited%20Online%20DCA%20US%7CU.%20of%20Michigan%20US-2%7CWvfiber%20US%7CVerizon%20NY%20Opt-Out%20US%7CAPI%20Digital-2%20US%7CiPrimus%20NJ%203%20US%7CInternap%20CHI%20US%7CBright.net%20US%7CCable%20%26%20Wireless%20DE%7CNetStar%20US%7CTerra-2%20BR%7CYMAX%20US%7CAlma%20Telco-2%20US%7CDnet-4%20US%7CAlma%20Telco%20US%7CUU%20Dial%2060%20US%7CSBC%20Clobal%20TX-2%20US%7CVerizon%20Dallas%20US%7CUltraDNS-2%7CLevel%203/GTEI-2%7CComodo%20Secure%20DNS%7CRadiant%20Alberta%20CA%7CSpeedNet-2%20Michigan%20US%7CEarthlink%20Opt-Out%20US-2%7CUU%20Cache%20US%7CMetConnect-1%20US%7CEarthlink%20Opt-Out%20US%7CUU%20Cache-2%20US%7CQwest-2%20US%7CAccess%20Northeast%20US%7CIntap%20US%7CComodo%20Secure%20DNS-2%7CVideotron%20Phone-4%20CA%7CUU%20Cache-7%20US%7CVerizon%20Boston%20US%7CInternap%20WDC%20US%7CTDS%208%20US%7C1scom%20US%7CVerizon%20NC%20US%7CEarthlink%20Ms%20US%7CNTT-2%7CInternap%20CHG%20US%7CQwest%20Redirect%20US%7CUU%20Cache-5%20US%7CSBC/AT%26T%20Global%20US%7CCIMCO-2%20US%7CLevel3-R2%7CUU%20Cache-4%20US%7CNorton%20DNS-2%20US%7CUU%20Cache-3%20US%7CBullEye%20Telecom%20US%7CCIMCO%20US%7CQwest%20US%7CWtechlink/Pacinfo/AT%26T-2%20US%7CInternap%20CHG-2%20US%7CUU%20Cache-2%20US-2%7CInternap%20Boston%20US%7CInternap%20Philadelphia%20US%7CWtechlink/AT%26T-2%20US%7CInternap%20NYC-2%20US%7CLevel3-R1%7CRCN%20ATW-2%20US%7CCogent%20WDC%20US%7CVerizon%20Philadelphia%20US%7CLevel%203/GTEI-4%7CAT%26T%20ASM%20US%7CSBC%20San%20Diego%20US%7CAT%26T%20New%20Orleans%20US%7CInternap%20NYC%20US%7COpenDNS%7COpenDNS-3%7CGenuity%20BAK%7CGoogle%20Public%20DNS-2%7CGoogle%20Public%20DNS%7C1%3A%7C0%7C320%7C640%7C960%7C1280%7C1600%7C1920%7C2240%7C2560%7C2570%7C2%3A%7CDuration%20in%20ms.
The whole HTML file I have uploaded here.
Created a fiddle with your code.
From the google developers image charts documentation
Specifying your chart as a URL in your browser or an tag is
called a GET request. Making a GET request is simple, but GET URLs are
limited to 2K characters. What if you have more data than that?
Luckily, the Chart API supports HTTP POST for chart requests up to 16K
long. The trade-off is the added complexity of using POST.
The first solution becomes using a POST . The link also contains examples of POST using either a form element, javascript or php.
The URL length limitation -
The maximum length of a URL is not determined by the Google Chart API,
but rather by web browser and web server considerations. The longest
URL that Google accepts in a chart GET request is 2048 characters in
length, after URL-encoding (e.g., | becomes %7C). For POST, this limit
is 16K.
The second solution: The same link provides the next type of solution, which is actually reducing the URL length :
If you are using a text encoding data format, remove leading zeros from numbers, remove trailing zeros after decimal points, and round or truncate the numbers after decimal points.
If that does not shorten the URL enough, use simple (1 character) or
extended (2 character) encoding.
Sample data less frequently; i.e., reduce granularity.
Remove accoutrements and decorations, such as colors, labels, and
styles, from your chart.
The first solution
This one applies for the first 2 charts , which have around 8000 characters which fit in a POST request (<16000):
<h2>Mean Response Duration</h2>
<h3>Fastest Individual Response Duration</h3>
i.e. you will have to write a POST through one of the methods described.
The second solution
This applies for the last 2 charts for which you get a 413 (Request Entity Too Large) status on get. These last 2 characters have around 20 000 characters, and the last 60 000 characters.
<h3>Response Distribution Chart (First 200ms)</h3>
<h3>Response Distribution Chart (Full)</h3>
Here you will indeed need to make the URL shorter through one of the methods advised. That is, shorter than 16000.
For testing purposes you could use a form such as this and change the parameters with what you need. Working fid
<form action='https://chart.googleapis.com/chart' method='POST' target="graph_target">
<input type="hidden" name="cht" value="lc" />
<input type="hidden" name="chtt" value="This is | my chart" />
<input type='hidden' name='chs' value='600x200' />
<input type="hidden" name="chxt" value="x,y" />
<input type='hidden' name='chd' value='t:40,20,50,20,100'/>
<input type="submit" />
</form>
<iframe name='graph_target' src='' style='width:600px;height:200px;'></iframe>
<script type="text/javascript">
document.forms["graphform"].submit();
</script>

Proper REST response for empty table?

Let's say you want to get list of users by calling GET to api/users, but currently the table was truncated so there are no users. What is the proper response for this scenario: 404 or 204?
I'd say, neither.
Why not 404 (Not Found) ?
The 404 status code should be reserved for situations, in which a resource is not found. In this case, your resource is a collection of users. This collection exists but it's currently empty. Personally, I'd be very confused as an author of a client for your application if I got a 200 one day and a 404 the next day just because someone happened to remove a couple of users. What am I supposed to do? Is my URL wrong? Did someone change the API and neglect to leave a redirection.
Why not 204 (No Content) ?
Here's an excerpt from the description of the 204 status code by w3c
The server has fulfilled the request but does not need to return an entity-body, and might want to return updated metainformation.
While this may seem reasonable in this case, I think it would also confuse clients. A 204 is supposed to indicate that some operation was executed successfully and no data needs to be returned. This is perfect as a response to a DELETE request or perhaps firing some script that does not need to return data. In case of api/users, you usually expect to receive a representation of your collection of users. Sending a response body one time and not sending it the other time is inconsistent and potentially misleading.
Why I'd use a 200 (OK)
For reasons mentioned above (consistency), I would return a representation of an empty collection. Let's assume you're using XML. A normal response body for a non-empty collection of users could look like this:
<users>
<user>
<id>1</id>
<name>Tom</name>
</user>
<user>
<id>2</id>
<name>IMB</name>
</user>
</users>
and if the list is empty, you could just respond with something like this (while still using a 200):
<users/>
Either way, a client receives a response body that follows a certain, well-known format. There's no unnecessary confusion and status code checking. Also, no status code definition is violated. Everybody's happy.
You can do the same with JSON or HTML or whatever format you're using.
I'd answer one of two codes depending on runtime situation:
404 (Not Found)
This answer is pretty correct if you have no table. Not just empty table but NO USER TABLE. It confirms exact idea - no resource. Further options are to provide more details WHY your table is absent, there is couple of more detailed codes but 404 is pretty good to refer to situation where you really have no table.
200 (OK)
All cases where you have table but it is empty or your request processor filtered out all results. This means 'your request is correct, everything is OK but you do not match any data just because either we have no data or we have no data which matches your request. This should be different from security denial answer. I also vote to return 200 in situation where you have some data and in general you are allowed to access table but have no access to all data which match your request (data was filtered out because of object level security but in general you are allowed to request).
If you are expecting list of user object, the best solution is returning an empty list ([]) with 200 OK than using a 404 or a 204 response.
definitely returns 200.
404 means resource not found. But the resource exists. And also, if the response has 404 status. How can you know users list empty or filled?
'/users' if is empty should return '200'.
'/users/1' if the id is not found. should return 404.
It must 200 OK with empty list.
Why: Empty table means the table exists but does not have any records.
404 Not Found means requested end point does not exist.

Responding to an idempotent HTTP POST request

Part of our RESTful API will allow users to register an item with a serial number. As the serial number is not globally unique it cannot be used as the identifier of the resource, so we'll use a POST to the parent resource which will generate an identifier, e.g.
POST /my/items
<item serial-number="ABCDEF" />
In the case where the item is not already registered, the HTTP semantics are well defined. We return a Location header, and the registered item as the entity body, e.g.
HTTP 201 Created
Location: /my/items/1234
<item id="1234" serial-number="ABCDEF" />
However, in the case where the item is already registered, the API should be idempotent and return the previously registered item without creating a new one. My best guess is that it should then return a 200 OK status code, and use the Content-Location header to indicate where the item actually came from, e.g.
HTTP 200 OK
Content-Location: /my/items/1234
<item id="1234" serial-number="ABCDEF" />
Would this seem reasonable? I'm not entirely clear whether the Location or Content-Location is more suitable in the second case.
I had similar requirement recently. For idempotent operations PUT is the best way. You're right there is a mismatch between the external-id and the internal one. I solved it by creating a dedicated resource for the external id target:
PUT /api-user/{username}/items/{serialNumber}
Internally I resolve it as a CREATE in case I have no item for 'username' and 'ABCDEF' serial number or UPDATE in case I do.
In case it was a CREATE I return 201 for an UPDATE 200. Further more the returned payload contains both homegrown id and the external serial number like you suggested in your payload.
Here is an interesting discussion on usages of the two headers. It claims Content-Location is not defined for PUT or POST so Location is possibly the better option in your case. It is certainly not clear cut which is better though.
Overall I think your approach makes sense though.

Question about a http form GET method, using query arguments

I am looking at a bug in WebSVN where when I get into a file log and click on compare, it looses the repository name as part of the request. The details are unimportant.
However, I've tracked down the bug to a http form that looks like this:
<form method="get" action="comp.php?repname=Binaries&" id="compare">
....
<input type="hidden" name="KEY" value="VALUE">
Is this supposed to work? Will both the "repname" argument, specified as part of the URL, and the hidden value be sent? It seems Chrome 4.1 only sends the hidden argument, and removes the repname parameter altogether. Is this correct?
I fixed it temporarily, pending more information, by adding another hidden field for repname with the same value, and now everything works, I'm just wondering if Chrome or WebSVN is in fault here.
you should remove the & from the end of the action value, that will likely just cause you trouble. if you need to pass an ampersand through, you should url-encode it as %26
edit: you should definitely do it the way you fixed it - by passing repname as another hidden variable - since some browsers do have weird behaviour when dealing with explicit and implicit url vars in a get :)

Input type "hidden" vs text area

I'm having a weird issue with an input type hidden and was wondering if anyone has ever seen something like this before. I'm saving about 2MB of data to a hidden field, in a comma separated format, then I'm posting that data to a jsp that simply sets some headers (so the output is recognized as an excel file) and then echoes the data.
I'm seeing that the variable that holds this data gets empty to the jsp side, even though I see that it's getting posted to the server (I'm seeing it with an HTTP sniffer) and all data seems to be contained correctly in the hidden field (I'm seeing that with firebug). However, if I change the object type to be a text area, the data is received correctly on the server's side.
Another weird thing I'm observing is that if I use URL encoding on the data, even using a text area, nothing gets to the server. If I don't use URL encoding but I have the hidden field, nothing gets saved to the field (it's empty when I check it with firebug). I don't understand that either...
I'm wondering if there is any special security setting that prevents the hidden fields to post big amounts of data to a Tomcat web server. Does anybody know anything about that?
If it makes any difference, I'm using the default enctype on the form (application/x-www-form-urlencoded)
I'm currently using a text are and setting the style to visibility "hidden" but it bothers me not to understand what's going on *sigh... Any suggestion is appreciated
I think having 2MB of data in a hidden field is a mistake regardless. You should store that kind of thing on the server as part of the session state, not send it back and forth between the server and the user, as you are doing. Instead, use a hidden field or cookie for the session variable*, which will be used to look up the 2MB of data.
*Don't do this by hand. JSP already has support for session state, among other things.
The server can't tell the difference between a textarea and textbox. All form elements are simply posted as name/value pairs.
Most likely, you have a double-quote somewhere in your data that's terminating the value attribute of the hidden input element. For example:
<input type="hidden" value="Double " quote" />
You need to escape the double-quotes by replacing them with "
<input type="hidden" value="Double " quote" />

Resources