Icalendar ICS update not working in google calendar - google-calendar-api

I have some trouble with the ICS attachment to Gmail/Google calendar addresses.
When I have to edit an event I send an update by mail with an ICS file with the same UID of the original event. However, GCalendar adds a second event. How can I overcome this?
This is first ICS file content:
BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VEVENT
DTSTART:20130425T090000
DTEND:20130425T100000
DTSTAMP:20130206T101100
ORGANIZER;CN=Test test:mailto:test#test.com
ATTENDEE:test#test.eu
UID:CALEVENT_TS090519840000000005
DESCRIPTION:test
SUMMARY:test
LOCATION:Test
SEQUENCE:1
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR
And this is the update ICS file content:
BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VEVENT
DTSTART:20130425T100000
DTEND:20130425T110000
DTSTAMP:20130206T101100
ORGANIZER;CN=Test test:mailto:test#test.com
ATTENDEE:test#test.eu
UID:CALEVENT_TS090519840000000005
DESCRIPTION:test
SUMMARY:test
LOCATION:Test
SEQUENCE:2
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR
When I receive the update files and I click on "add this event to calendar" I will find two different events.
This is the original raw email:
Delivered-To: test#test.eu
Received: by 10.216.231.19 with SMTP id k19csp190640weq;
Sat, 9 Feb 2013 08:01:11 -0800 (PST)
X-Received: by 10.194.7.136 with SMTP id j8mr15530679wja.38.1360425671327;
Sat, 09 Feb 2013 08:01:11 -0800 (PST)
Return-Path: <test#test.eu>
Received: from mxavas8.aruba.it (mxavas8.aruba.it. [62.149.157.18])
by mx.google.com with SMTP id 45si59706250eeg.83.2013.02.09.08.01.11;
Sat, 09 Feb 2013 08:01:11 -0800 (PST)
Received-SPF: neutral (google.com: 62.149.157.18 is neither permitted nor denied by best guess record for domain of test#test.eu) client-ip=62.149.157.18;
Authentication-Results: mx.google.com;
spf=neutral (google.com: 62.149.157.18 is neither permitted nor denied by best guess record for domain of test#test.eu) smtp.mail=test#test.eu
Received: (qmail 4991 invoked by uid 89); 9 Feb 2013 16:01:10 -0000
Delivered-To: test.eu-test#test.eu
Received: (qmail 4424 invoked by uid 89); 9 Feb 2013 16:01:04 -0000
Received: from unknown (HELO mxcmd03.ad.aruba.it) (10.10.10.67)
by mxavas8.ad.aruba.it with SMTP; 9 Feb 2013 16:01:04 -0000
Received: from smtpdg11.aruba.it ([62.149.158.229])
by mxcmd03.ad.aruba.it with bizsmtp
id yFwi1k01A4xF4Fy01G14N7; Sat, 09 Feb 2013 17:01:04 +0100
Received: from localhost ([79.54.181.227])
by smtpcmd04.ad.aruba.it with bizsmtp
id yG141k0074umbYX01G140P; Sat, 09 Feb 2013 17:01:04 +0100
Date: Sat, 9 Feb 2013 17:01:04 +0100
Return-Path: test#test.eu
To: test#test.eu
From: Event notification <test#test.eu>
Reply-To: Event notification <test#test.eu>
Subject: New Event
Message-ID: <238497c6d05cffae45716486e74a8009#localhost>
X-Priority: 3
X-Mailer: PHPMailer 5.2.2 (http://code.google.com/a/apache-extras.org/p/phpmailer/)
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="b1_238497c6d05cffae45716486e74a8009"
X-Spam-Rating: mxavas8.ad.aruba.it 1.6.2 0/1000/N
--b1_238497c6d05cffae45716486e74a8009
Content-Type: multipart/alternative;
boundary="b2_238497c6d05cffae45716486e74a8009"
--b2_238497c6d05cffae45716486e74a8009
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
test
DateTimeRoom
02/05/201309.00 - 10.15ROOM1
--b2_238497c6d05cffae45716486e74a8009
Content-Type: text/html; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;">
<style type="text/css">
<!--
td{ background-color: #eee; }
-->
</style>
</head>
<body style="font-family: Arial, Helvetica, sans-serif; color: #333;">
<p style="text-align:center;"><img src="images/logo2.png" alt="Logo" /></p>
<hr style="border: 1px solid #ccc; width: 80%;" />
<div style=" width: 80%; margin: 10px auto;">
<h4></h4>
<h3>test</h3>
<table style="width: 400px; table-layout: fixed; border: 1px solid #ccc;">
<tr><th>Date</th><th>Time</th><th>Room</th></tr>
<tr><td>02/05/2013</td><td>09.00 - 10.15</td><td>ROOM 1</td></tr>
</table>
</div>
</body>
</html>
--b2_238497c6d05cffae45716486e74a8009--
--b1_238497c6d05cffae45716486e74a8009
Content-Type: text/calendar; name="event.ics"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="event.ics"
BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
PRODID:tsCalendar
METHOD:REQUEST
BEGIN:VEVENT
DTSTART:20130502T090000
DTEND:20130502T101500
DTSTAMP:20130209T170100
ORGANIZER:mailto:test#test.eu
ATTENDEE:mailto:test#test.eu
UID:CALEVENT_TS090519840000000013
DESCRIPTION:test
SUMMARY:test
LOCATION:ROOM1 (floor: prova)
SEQUENCE:1
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR
--b1_238497c6d05cffae45716486e74a8009--
Here are the other tests with the ORGANIZER email the same as the Sender email and ATTENDEE email the same as Receiver email.
Creating http://tny.cz/6396ba62
Updating http://tny.cz/08ac81c0

Some of the answers provided are not (entirely) correct.
In short, your ATTENDEE property needs more arguments to make sure Google Calendar considers it an update:
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=
TRUE;CN=Recipient Name;X-NUM-GUESTS=0:mailto:recipient#gmail.com
I had the same problem and to find the answer I:
Sent myself an invitation using Google Calendar itself + an updated invitation
Compared the two .ics files
Ran many different self-generated variations on those two .ics files to find out which parameters were really necessary
These are my findings:
Increment SEQUENCE from 0 to 1 (or further if you want to update updates)
METHOD has to be REQUEST (*1)
Email sender does NOT need to be the same as ORGANIZER (Sidenote: It is however, not possible in Google Calendar to update an ORGANIZER)
ORGANIZER does NOT need to be listed as an ATTENDEE
Email recipient has to be an ATTENDEE
Also (as mentioned above), the ATTENDEE needs additional parameters, not just :mailto
STATUS does NOT need to be provided. EDIT: This is the case when sending invites to google calendar / chrome / mac, but the invite doesn't get a proper preview in other combinations it seems
Arguments that take several lines in the doc should be indented by one space on the next line
In iCalender objects generated by Google Calendar you may notice that lines that are too long are broken into several lines into the document, however this is not required (e.g. you can provide a description that is a very long string, just make sure it only takes one line or cut it in lines where every line is indented with one space)
Bonus Tip: Use same UID in original invite and update (this is actually not required BUT makes sure your historical test results remain unaffected...)
Bonus Tip 2: for easier testing, also change the SUMMARY and subject of your email each time
Cleaned up example:
BEGIN:VCALENDAR
PRODID:-//YourCompany/AppName//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VEVENT
DTSTART:20180331T150000
DTEND:20180331T160000
DTSTAMP:20180331T150000 // make sure to populate this dynamically
ORGANIZER;CN=organizer#gmail.com:mailto:organizer#gmail.com
UID:BESTIDEVER123
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=
TRUE;CN=Recipient Name;X-NUM-GUESTS=0:mailto:recipient#gmail.com
CREATED:20180331T150000 // make sure to populate this dynamically
DESCRIPTION:Best event evah
LAST-MODIFIED:20180331T150000 // make sure to populate this dynamically
LOCATION:
SEQUENCE:0 // don't forget to increment this!!
SUMMARY:A Wonderful Event
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
(*1) The only question that I could not figure out is how to have a METHOD:PUBLISH that can be updated - I am trying to make a calendar publishing app that should NOT take replies. If anyone can figure that out I would be very grateful. :-)

see RFC5546 Update an Event
The event is moved to a different time. The combination of the "UID"
property (unchanged) and the "SEQUENCE" (bumped to 1) properties
indicate the update.
in your case given what you shared you probably need to add a SEQUENCE property in your ical file and increment it for every update you make.
Update:
given the ical file you added, you are missing the organiser and attendee fields with below file the update work
BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
PRODID:pyICSParser
METHOD:REQUEST
BEGIN:VEVENT
DTSTART:20130425T090000
DTEND:20130425T100000
DTSTAMP:20130206T101100
ORGANIZER:mailto:organiser#example.com
ATTENDEE:mailto:attendee#example.com
UID:CALEVENT_TS090519840000000005
DESCRIPTION:test
SUMMARY:test
LOCATION:Test
SEQUENCE:1
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR
Also you need to match the email address of the sender with the one from organiser and same about the attendee, something like below has been validated with google calendar.
eml_as_string:
Subject: New Event
Message-ID: <238497c6d05cffae45716486e74a8009#localhost>
X-Priority: 3
X-Mailer: PHPMailer 5.2.2 (http://code.google.com/a/apache-extras.org/p/phpmailer/)
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="b1_238497c6d05cffae45716486e74a8009"
X-Spam-Rating: mxavas8.ad.aruba.it 1.6.2 0/1000/N
--b1_238497c6d05cffae45716486e74a8009
Content-Type: multipart/alternative;
boundary="b2_238497c6d05cffae45716486e74a8009"
--b2_238497c6d05cffae45716486e74a8009
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
test
DateTimeRoom
02/05/201309.00 - 10.15ROOM1
--b2_238497c6d05cffae45716486e74a8009
Content-Type: text/html; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;">
<style type="text/css">
<!--
td{ background-color: #eee; }
-->
</style>
</head>
<body style="font-family: Arial, Helvetica, sans-serif; color: #333;">
<p style="text-align:center;"><img src="images/logo2.png" alt="Logo" /></p>
<hr style="border: 1px solid #ccc; width: 80%;" />
<div style=" width: 80%; margin: 10px auto;">
<h4></h4>
<h3>test</h3>
<table style="width: 400px; table-layout: fixed; border: 1px solid #ccc;">
<tr><th>Date</th><th>Time</th><th>Room</th></tr>
<tr><td>02/05/2013</td><td>09.00 - 10.15</td><td>ROOM 1</td></tr>
</table>
</div>
</body>
</html>
--b2_238497c6d05cffae45716486e74a8009--
--b1_238497c6d05cffae45716486e74a8009
Content-Type: text/calendar; name="event.ics"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="event.ics"
BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
PRODID:tsCalendar
METHOD:REQUEST
BEGIN:VEVENT
DTSTART:20130502T090000
DTEND:20130502T101000
DTSTAMP:20130209T170100
ORGANIZER:mailto:test#test.eu
ATTENDEE:mailto:test#test.eu
UID:CALEVENT_TS090519840000000013
DESCRIPTION:test
SUMMARY:test
LOCATION:ROOM1 (floor: prova)
SEQUENCE:1
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR
--b1_238497c6d05cffae45716486e74a8009--
on which below script was applied:
# -*- coding:utf-8 -*-
import smtplib
def sendInvite(fro,to,emlasstring):
mailServer = smtplib.SMTP('smtp.gmail.com', 587)
mailServer.ehlo()
mailServer.starttls()
mailServer.ehlo()
mailServer.login(login, password)
mailServer.sendmail(fro, to, emlasstring)
mailServer.close()
newUID = "UID:newCALEVENT_TS090519840000000016"
#needed to change UID as once an event was sent its UID is locked and a few attempts were needed to make the script work
eml = open("SO14712929_1.eml",'r').read()
emlhead = "To: "+attendee_eml+CRLF
emlhead += "From:"+fro+CRLF
emlhead += "Reply-To: "+fro+CRLF
eml = emlhead+eml
eml = eml.replace("ORGANIZER:mailto:test#test.eu","ORGANIZER:mailto:"+fro_eml)
eml = eml.replace("ATTENDEE:mailto:test#test.eu","ATTENDEE:mailto:"+attendee_eml)
eml = eml.replace("UID:CALEVENT_TS090519840000000013",newUID)
sendInvite(fro,attendees,eml)
print "invite sent"
eml = open("SO14712929_2.eml",'r').read()
emlhead = "To: "+attendee_eml+CRLF
emlhead += "From:"+fro+CRLF
emlhead += "Reply-To: "+fro+CRLF
eml = emlhead+eml
eml = eml.replace("ORGANIZER:mailto:test#test.eu","ORGANIZER:mailto:"+fro_eml)
eml = eml.replace("ATTENDEE:mailto:test#test.eu","ATTENDEE:mailto:"+attendee_eml)
eml = eml.replace("UID:CALEVENT_TS090519840000000013",newUID)
sendInvite(fro,attendees,eml)
print "updated invite sent"

Try with METHOD:PUBLISH instead of METHOD:REQUEST

Related

How do I extract the "href" attributes from a HTML document with select.rs?

I am trying to write a very basic crawler. After receiving an HTTP response, I am using the select.rs crate to extract the URLs from the body for further crawling.
How can I extract these URLs from from the "document" which is the "body" part of the HTTP response using the "for-iteration"?
extern crate hyper;
extern crate select;
extern crate xhtmlchardet;
extern crate robotparser;
extern crate url;
use std::io::Read;
use Crawler::hyper::client::Client;
use Crawler::hyper::header::Connection;
use Crawler::select::document::Document;
use Crawler::select::predicate::*;
pub fn crawl(url: &str) {
//Opens up a new HTTP client
let client = Client::new();
//Creates outgoing request
let mut res = client.get(&*url)
.header(Connection::close())
.send().unwrap();
//Reads the response
let mut body = String::new();
res.read_to_string(&mut body).unwrap();
println!("Response: {}", res.status);
println!("Headers:\n{}", res.headers);
println!("Body:\n{}", body);
let document = Document::from_str(&*body);
for node in document.find(Attr("id", "hmenus")).find(Name("a")).iter() {
println!("{} ({:?})", node.text(), node.attr("href").unwrap());
}
}
The result of executing crawl for a URL like "um.ac.ir" is a full HTTP response with a body. I am trying to extract the hrefs from this output.
Response: 200 OK
Headers:
X-Content-Type-Options: nosniff
X-Frame-Options: sameorigin
Cache-Control: cache
Date: Tue, 27 Feb 2018 13:16:27 GMT
Vary: Accept-Encoding
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Transfer-Encoding: chunked
Pragma: no-cache
Server: GFW/2.0
Connection: close
Content-Type: text/html; charset=utf-8
Strict-Transport-Security: max-age=63072000; preload
Set-Cookie: POSTNUKESID=pnd2nuadgastqak5h6nop87c63; path=/
...
<div class="col-md-4">
<h3>سایر</h3>
<ul>
<li><a target="_blank" href="http://ftpnews.um.ac.ir/">سایت خبری ftp دانشگاه</a></li>
<li><a target="_blank" href="http://news.um.ac.ir/Topic96.html">گزینش دانشگاه </a></li>
<li><a target="_blank" href="http://herasat.um.ac.ir/index.php?lang=fa">مدیریت حراست دانشگاه </a></li>
<li><a target="_blank" href="http://mafakher.um.ac.ir/">مركز آثارمفاخر و اسناد دانشگاه</a></li>
<li><a target="_blank" href="http://intr.um.ac.ir/">مدیریت همكاری های علمی و بین المللی</a></li>
<li><a target="_blank" href="http://eva.um.ac.ir/"> مدیریت نظارت و ارزیابی دانشگاه</a></li>
<li><a target="_blank" href="http://saybanemehr.um.ac.ir/">سایت سایبان مهر</a></li>
<li><a target="_blank" href="http://faf.um.ac.ir/">بنیاد دانشگاهی فردوسی</a></li>
<li><a target="_blank" href="http://ads.um.ac.ir/">آگهي ها و تبليغات دانشگاه</a></li>
<li><a target="_blank" href="http://fumblog.um.ac.ir/">سامانه مدیریت وبلاگ</a></li>
<li><a target="_blank" href="http://basijasatid.um.ac.ir/">بسیج اساتید</a></li>
<li><a target="_blank" href="http://basij.um.ac.ir/">بسیج كاركنان</a></li>
<li><a target="_blank" href="http://nahad.um.ac.ir/">نهاد نمایندگی رهبری در دانشگاه</a></li>
</ul>
</div>
...
The problem is that the println!("{} ({:?})", node.text(), node.attr("href").unwrap()) doesn't output anything since the [...].iter() is not working correctly:
for node in document.find(Attr("id", "hmenus")).find(Name("a")).iter() {
println!("{} ({:?})", node.text(), node.attr("href").unwrap());
}
It seems that find(Attr("id", "hmenus")).find(Name("a")) isn't the right way for finding "href" tags from the body of the HTTP response.
I believe rewriting this part should fix the problem in my code, although it requires an overall knowledge of how select::document is working.
I assume you copied the Attr("id", "hmenus") from some example code. This is a filter predicate that matches an HTML node containing attribute id="hmenus". Your example page um.ac.ir does not contain any nodes with attribute id="hmenus". If you want the crawler to find all <a> nodes on the page, the filter predicate would be Name("a").
for node in document.find(Name("a")).iter() {
if let Some(href) = node.attr("href") {
println!("{} ({:?})", node.text().trim(), href);
}
}

Grails request.getFile always returning null

I've been trying to submit a form that contains multiple inputs (texts and one image) but I'm unable to retrieve the image from request (Grails 3.0.4)
My create.gsp looks like this:
<g:uploadForm controller="advertisement" action="save">
<input name="name" type="text" id="advertisement_name" />
<input name="link" type="text" id="advertisement_url" />
<input id="add_banner_image" name="myimage" type="file" accept="image/png,image/jpeg" data-max-size="512000"/>
<g:submitButton name="save" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent" value="Salvar anúncio">
</g:submitButton>
</g:uploadForm>
My browser shows the correct request payload:
------WebKitFormBoundarysaAgHUi2q9vTfkkY
Content-Disposition: form-data; name="name"
Filipe
------WebKitFormBoundarysaAgHUi2q9vTfkkY
Content-Disposition: form-data; name="link"
https://www.filipescosta.com
------WebKitFormBoundarysaAgHUi2q9vTfkkY
Content-Disposition: form-data; name="imagemlouca"; filename="exemplo.jpeg"
Content-Type: image/jpeg
------WebKitFormBoundarysaAgHUi2q9vTfkkY
Content-Disposition: form-data; name="save"
Salvar anúncio
My resources.groovy looks like this:
beans = {
multipartResolver (org.springframework.web.multipart.commons.CommonsMultipartResolver) {
maxUploadSize=2500000
}
}
And my application.yml looks like this:
grails:
mime:
disable:
accept:
header:
userAgents:
- Gecko
- WebKit
- Presto
- Trident
types:
all: '*/*'
atom: application/atom+xml
css: text/css
csv: text/csv
form: application/x-www-form-urlencoded
html:
- text/html
- application/xhtml+xml
js: text/javascript
json:
- application/json
- text/json
multipartForm: multipart/form-data
pdf: application/pdf
rss: application/rss+xml
text: text/plain
hal:
- application/hal+json
- application/hal+xml
xml:
- text/xml
- application/xml
urlmapping:
cache:
maxsize: 1000
controllers:
defaultScope: singleton
converters:
encoding: UTF-8
views:
default:
codec: html
gsp:
encoding: UTF-8
htmlcodec: xml
codecs:
expression: html
scriptlets: html
taglib: none
staticparts: none
My Controller looks like this:
def save() {
println request.getFile('myimage')
println "Request class: ${request.class}"
[...]
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.created.message', args: [message(code: 'advertisement.label', default: 'Advertisement'), advertisement.id])
redirect(uri:'/')
}
'*' { respond advertisement, [status: CREATED, formats:['html']] }
}
}
But in console, the println message is:
null
Request class: class org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest
Can anyone take a look and help me with some trick? I've been searching examples and I couldn't find anything that helps.
You define: attribute name="myimage"
and try get with Uppercase name -> request.getFile('myImage')
Well, I figured out what was going on.
I was trying to create a new object with String type, but I was sending an input file type as a parameter.
Then, after trying to set the input type String to a file type, the code broke and I wasn't able to print the value of request.getFile.

No response from web service when a POST is sent from client

My web service uses asp.net web api. Currently my api controller doesn't do anything because I want to inspect the post to see what I'm working with here.
You'll notice that I'm posting to localhost. That's because currently I'm only running the service app in the debugger so that I can inspect the post via a Watch.
My problem is that it doesn't seem like my post is going anywhere. The breakpoint that I've set on the Post void never gets hit when I submit the form from the webpage.
Am I misunderstanding how this is supposed to work here?
Controller
public class CashbackController : ApiController
{
// POST api/<controller>
public void Post([FromBody]string value)
{
}
}
Client web page
<form action="http://localhost:49474/api/Cashback" method="post">
<p>
API Key: <input type="text" name="_apikey" /><br />
Receipt No: <input type="text" name="_receipt" /><br />
Purchase Date: <input type="text" name="_date" /><br />
Cashback Total: <input type="text" name="_cashback" />
</p>
</form>
<p><input type="submit" value="Submit" /></p>
<script>
$(document).ready(function() {
alert("JQuery works");
});
$("input[type=submit]").on("click", function () {
$("form").submit();
});
$("form").submit(function () {
$.post($(this).attr("action"), $(this).serialize(), function(data) {
if (!data.IsOK) {
alert("Error: " + data.Error);
}
else
{
alert("Post successful.");
}
return;
});
return false;
});
</script>
EDIT
Inspecting with fiddler, it doesn't look as though my clicking on the submit button is doing anything at all...
Correctly referenced jquery and fiddler caught this:
POST http://localhost:49474/api/Cashback HTTP/1.1
Host: localhost:49474
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0
Accept: /
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://localhost/servicepost/
Content-Length: 85
Origin: http://localhost
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
_apikey=abcdefghijklmnopqrstuvwxyz&_receipt=1234567890&_date=2015-03-31&_cashback=100
However, in my controller, value is still null
Mkay so there were a few things wrong here...
First, I hadn't referenced the correct jquery source
NOTE: Only ever use the googleapis link(this one is to jquery 2.1.3.min) or another such link as you see fit. It's just simpler
Secondly, my controller wasn't accepting the correct type. Now this is where I really got confused because the client app isn't going to know what models my api uses.
Turns out it's just a matter of mirroring the model on the client app that posts to the api. So consider the following
public class UserController : ApiController
{
// POST api/<controller>
public void Post([FromBody]User Value)
{
}
}
public class User
{
public int ID { get; set; }
public string Username { get; set; }
public string EmailAddress { get; set; }
}
The form must post a mirror of the model which in this case would look something like this:
<form method="post" action="path-to-service/api/User">
<div>
Username: <input type="text" name="Username" /><br />
Email Address: <input type="text" name="EmailAddress" />
</div>
</form>
The ajax post above will work but will need to be modified to do exactly what you want it to. Typically I just throw in some error handling into at if statement and a redirect into the else.

Can't convert form data to URL

I'm trying to send a POST request to get a file downloaded, but I'm having problem complete this operation using URL.
The form looks like this:
<FORM action='download.php' method='post' encType='multipart/form-data'>
<TD bgcolor="white" valign="top" style="padding:10px;">
<TABLE cellspacing=0 cellpadding=0 width='100%'>
<TR>
<TD width='30%' align='center'>
Uploaded torrent code (date+hash):<BR>
<INPUT size=58 name="ref" value="1333f4f84bb41d5adc0f61e8f5a4658460da70b2737" style="font-size:10px;"><INPUT TYPE="hidden" NAME="reff" value="MTM3OTU2Mjk4OQ=="><BR>
downloaded: 27988<BR>
<INPUT type="submit" height=27 width=174 value=download border=0 name=submit valign="bottom" onclick="setpos(1);">
</TD>
</TR>
</TABLE>
</TD>
</FORM>
So I tried to use URL:
www.site.com/download.php?ref=1333f4f84bb41d5adc0f61e8f5a4658460da70b2737
but that doesn't work. Chrome seems to show me a browser based form data:
------WebKitFormBoundaryeqA3pQupG0ndfLMZ
Content-Disposition: form-data; name="ref"
1333f4f84bb41d5adc0f61e8f5a4658460da70b2737
------WebKitFormBoundaryeqA3pQupG0ndfLMZ
Content-Disposition: form-data; name="reff"
MTM3OTQ4NzQwMQ==
------WebKitFormBoundaryeqA3pQupG0ndfLMZ
Content-Disposition: form-data; name="submit"
download
------WebKitFormBoundaryeqA3pQupG0ndfLMZ--
What should I do now?
Post request can't be made in browser url.
-> This is is first way to do this
Sample post request using curl:
curl -F param1=val1 -F param2=val2 -F param3=val3 http://host:port/abc.json
Hit this in terminal/console/cmd
curl -F ref=1333f4f84bb41d5adc0f61e8f5a4658460da70b2737 www.site.com/download.php
-> Or install RestConsole in chrome browser using Google Web Store. There you can handle every kind of request.

curl + jsecurity authentication

I have a grails app that is using jsecurity plugin for authentication.
How do I use curl to send my credentials? If I just do curl -u username mysite
I get a prompt for a password, then nothing.
I tried to do an anyauth command and this is what I got for the site. Any idea why it is returning a 302?
dcole#DCOLE-L /cygdrive/c/dev
$ curl --anyauth --verbose http://localhost:8080/SkillsDB
* About to connect() to localhost port 8080 (#0)
* Trying ::1... connected
* Connected to localhost (::1) port 8080 (#0)
> GET /SkillsDB HTTP/1.1
> User-Agent: curl/7.20.1 (i686-pc-cygwin) libcurl/7.20.1 OpenSSL/0.9.8o zlib/1.
2.5 libidn/1.18 libssh2/1.2.5
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 302 Moved Temporarily
< Server: Apache-Coyote/1.1
< Location: http://localhost:8080/SkillsDB/
< Transfer-Encoding: chunked
< Date: Thu, 07 Oct 2010 14:32:32 GMT
<
* Connection #0 to host localhost left intact
* Closing connection #0
here is additional information:
Rob is correct that it is form based. When I go to the address
http://localhost:8080/SkillsDB/auth/initialLogin
This is the form code that is displayed:
<form action="/SkillsDB/auth/initialSignIn" method="post" name="logform" id="logform">
<input name="targetUri" value="" type="hidden">
<input value="" widgetid="username" tabindex="0" id="username" class="dijit dijitReset dijitLeft dijitTextBox" dojoattachpoint="textbox,focusNode" name="username" dojoattachevent="onmouseenter:_onMouse,onmouseleave:_onMouse,onfocus:_onMouse,onblur:_onMouse,onkeypress:_onKeyPress" autocomplete="off" type="text"></td>
<input value="" widgetid="password" tabindex="0" id="password" class="dijit dijitReset dijitLeft dijitTextBox" dojoattachpoint="textbox,focusNode" name="password" dojoattachevent="onmouseenter:_onMouse,onmouseleave:_onMouse,onfocus:_onMouse,onblur:_onMouse,onkeypress:_onKeyPress" autocomplete="off" type="password"></td>
<td style=""><span widgetid="dijit_form_Button_0" class="dijit dijitReset dijitLeft dijitInline dijitButton" dojoattachevent="ondijitclick:_onButtonClick,onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse"><span class="dijitReset dijitRight dijitInline"><span class="dijitReset dijitInline dijitButtonNode"><button style="-moz-user-select: none;" tabindex="0" value="Log In" id="dijit_form_Button_0" aria-labelledby="dijit_form_Button_0_label" role="button" class="dijitReset dijitStretch dijitButtonContents" dojoattachpoint="titleNode,focusNode" name="" type="submit" wairole="button" waistate="labelledby-dijit_form_Button_0_label"><span class="dijitReset dijitInline" dojoattachpoint="iconNode"><span class="dijitReset dijitToggleButtonIconChar">✓</span></span><span class="dijitReset dijitInline dijitButtonText" id="dijit_form_Button_0_label" dojoattachpoint="containerNode">Log In</span></button></span></span></span></td>
</form>
If you're using a form-based authentication method, it's likely you're going to have to make an HTTP POST request to your login form, something along the lines of:
curl --data="username=foo&password=bar" http://localhost:8080/SkillsDB/login/auth
# note that '--data' causes the request to be a POST
I can't remember what JSecurity's login action is, but you'll have to replace login/auth (in the curl command above) with it. Have a look at the action of the <form> that the login page submits to.
Note that you'll be passing the password as plain text here. You'll probably want to use HTTPS for this transaction, but that's a whole different question.
Unless JSecurity is extending its authentication to use HTTP Basic Authentication, using the --anyauth is not likely to work, as I would imagine curl uses that to determine the proper HTTP authentication method.
Regarding your question about the 302, what happens when you add --location to your curl arguments? That should make curl follow the Location header that comes back in the response.

Resources