Hi, we've been trying to implement a PHP script which accepts requests from Collect and sends them to Aggregate. The reason why we are doing this is because we need to restrict which user can see which forms, something that isn't possible with Aggregate. So far, we've been able to implement the user login and the forms list through /formList. We are trying to implement form submission (/submission), but we are struggling with the PHP code. It appears that the API used to submit data is not really documented and doesn't appear to follow the OpenRosa standard described here:
Seems to indicate that the communication between Collect and Aggregate relies on a 204 http response which is not mentioned in the OpenRosa standards. Also, it seems to also require a Location: in the header, which is contradictory with the "204 No Content" response. In PHP, issuing a Location in the header automatically converts the response into a 301 or 302 and ignores the 204.
Does anybody have a functioning PHP code sample to intercept data sent from Collect?
I tried to use other PHP code samples posted in previous threads, but they appear to only issue a 204 reponse with no Location, which doesn't appear to work in recent versions of Collect.
I've answered my own question shortly after posting this. It looks like you can trick PHP into issuing 204 response while having a Location in the header with this simple command:
I'm now able to intercept the posted files and send them to Agggregate.
Cheers,
Guillaume
···
On Monday, June 8, 2015 at 12:55:30 PM UTC-4, gla...@gmail.com wrote:
> Hi, we've been trying to implement a PHP script which accepts requests from Collect and sends them to Aggregate. The reason why we are doing this is because we need to restrict which user can see which forms, something that isn't possible with Aggregate. So far, we've been able to implement the user login and the forms list through /formList. We are trying to implement form submission (/submission), but we are struggling with the PHP code. It appears that the API used to submit data is not really documented and doesn't appear to follow the OpenRosa standard described here:
>
> https://bitbucket.org/javarosa/javarosa/wiki/FormSubmissionAPI
>
> The code in Collect:
>
> https://code.google.com/p/opendatakit/source/browse/src/org/odk/collect/android/tasks/InstanceUploaderTask.java?repo=collect
>
> Seems to indicate that the communication between Collect and Aggregate relies on a 204 http response which is not mentioned in the OpenRosa standards. Also, it seems to also require a Location: in the header, which is contradictory with the "204 No Content" response. In PHP, issuing a Location in the header automatically converts the response into a 301 or 302 and ignores the 204.
>
> Does anybody have a functioning PHP code sample to intercept data sent from Collect?
>
> I tried to use other PHP code samples posted in previous threads, but they appear to only issue a 204 reponse with no Location, which doesn't appear to work in recent versions of Collect.
>
> Thank you very much,
>
> Guillaume
Can someone please share the PHP working code the accepts form substitutions and put them into my sql database...
Thank you
···
On Monday, June 8, 2015 at 7:55:30 PM UTC+3, gla...@gmail.com wrote:
> Hi, we've been trying to implement a PHP script which accepts requests from Collect and sends them to Aggregate. The reason why we are doing this is because we need to restrict which user can see which forms, something that isn't possible with Aggregate. So far, we've been able to implement the user login and the forms list through /formList. We are trying to implement form submission (/submission), but we are struggling with the PHP code. It appears that the API used to submit data is not really documented and doesn't appear to follow the OpenRosa standard described here:
>
> https://bitbucket.org/javarosa/javarosa/wiki/FormSubmissionAPI
>
> The code in Collect:
>
> https://code.google.com/p/opendatakit/source/browse/src/org/odk/collect/android/tasks/InstanceUploaderTask.java?repo=collect
>
> Seems to indicate that the communication between Collect and Aggregate relies on a 204 http response which is not mentioned in the OpenRosa standards. Also, it seems to also require a Location: in the header, which is contradictory with the "204 No Content" response. In PHP, issuing a Location in the header automatically converts the response into a 301 or 302 and ignores the 204.
>
> Does anybody have a functioning PHP code sample to intercept data sent from Collect?
>
> I tried to use other PHP code samples posted in previous threads, but they appear to only issue a 204 reponse with no Location, which doesn't appear to work in recent versions of Collect.
>
> Thank you very much,
>
> Guillaume
The 204 is expected to be returned in response to a HEAD request from ODK
Collect.
Every submission starts with a HEAD request followed by a POST.
This is done to (a) detect network login pages and (b) negotiate
authentication credentials prior to issuing the large POST of data when
submitting.
···
On Mon, Jun 8, 2015 at 10:42 AM, wrote:
I've answered my own question shortly after posting this. It looks like
you can trick PHP into issuing 204 response while having a Location in the
header with this simple command:
I'm now able to intercept the posted files and send them to Agggregate.
Cheers,
Guillaume
On Monday, June 8, 2015 at 12:55:30 PM UTC-4, gla...@gmail.com wrote:
Hi, we've been trying to implement a PHP script which accepts requests
from Collect and sends them to Aggregate. The reason why we are doing this
is because we need to restrict which user can see which forms, something
that isn't possible with Aggregate. So far, we've been able to implement
the user login and the forms list through /formList. We are trying to
implement form submission (/submission), but we are struggling with the PHP
code. It appears that the API used to submit data is not really documented
and doesn't appear to follow the OpenRosa standard described here:
Seems to indicate that the communication between Collect and Aggregate
relies on a 204 http response which is not mentioned in the OpenRosa
standards. Also, it seems to also require a Location: in the header, which
is contradictory with the "204 No Content" response. In PHP, issuing a
Location in the header automatically converts the response into a 301 or
302 and ignores the 204.
Does anybody have a functioning PHP code sample to intercept data sent
from Collect?
I tried to use other PHP code samples posted in previous threads, but
they appear to only issue a 204 reponse with no Location, which doesn't
appear to work in recent versions of Collect.
Here is code for a formList/index.php file that will intercept Collect submissions, validate the login and password of the user, and only show forms submitted by this user. Note that this is in PostgreSQL, not MySQL.
$error = false;
$elog = "";
if (empty($_SERVER['PHP_AUTH_DIGEST'])){ // before credentials
http_response_code(401);
header("HTTP/1.1 401 Unauthorized");
header('Content-Type: text/xml; charset=utf-8');
header('WWW-Authenticate: Digest realm="**INSERT YOUR REALM HERE**",qop="auth",nonce="'.uniqid().'",opaque="'.md5('**INSERT YOUR REALM HERE**').'"');
header('"HTTP_X_OPENROSA_VERSION": "1.0"');
header('X-OpenRosa-Version:1.0');
} else { // after credentials
header('Content-Type: text/xml; charset=utf-8');
header('"HTTP_X_OPENROSA_VERSION": "1.0"');
header('X-OpenRosa-Version:1.0');
$uid=check_user_pass();
if ($uid!==false){
echo '<xforms xmlns="http://openrosa.org/xforms/xformsList">';
$uid = pg_escape_literal($uid);
$query = 'SELECT * FROM odk_prod._form_info WHERE "_CREATOR_URI_USER" = '.$uid.' AND "_IS_COMPLETE" = TRUE';
$result = pg_query($con_pg, $query);
if (!$result) {
$error = true;
} else {
while ($row = pg_fetch_assoc($result)) {
$form = $row["FORM_ID"];
$query = 'SELECT "FORM_NAME", "ROOT_ELEMENT_MODEL_VERSION" FROM odk_prod._form_info_fileset WHERE "_TOP_LEVEL_AURI" = \''.$row['_URI'].'\'';
$result_ref = pg_query($con_pg,$query);
$row_ref=pg_fetch_assoc($result_ref);
echo '<xform>';
echo '<formID>'.$form.'</formID>';
echo '<name>'.$row_ref['FORM_NAME'].'</name>';
echo '<majorMinorVersion>'.$row_ref['ROOT_ELEMENT_MODEL_VERSION'].'</majorMinorVersion>';
echo '<version>'.$row_ref['ROOT_ELEMENT_MODEL_VERSION'].'</version>';
echo '<hash>'.$row['_URI'].'</hash>';
echo '<downloadUrl>http://quebio.ca/odk/formXML/?formId='.$form.'</downloadUrl>';
$query = 'SELECT * FROM odk_prod._form_info_manifest_bin WHERE "_TOP_LEVEL_AURI" = \''.$row['_URI'].'\'';
$result2 = pg_query($con_pg, $query);
if (pg_num_rows($result2)>0){
echo '<manifestUrl>http://**YOUR_SERVER_ADDRESS**/formList/xformsManifest.php?formId='.$form.'</manifestUrl>';
}
echo '</xform>';
}
}
echo '</xforms>';
}
// query db for hashed password for given username
if (!$error){
$name = pg_escape_literal($name);
$query = 'SELECT * FROM odk_prod._registered_users WHERE "LOCAL_USERNAME" = '.$name.' AND "IS_REMOVED" = FALSE';
$result = pg_query($con_pg, $query);
if (!$result) {
$error = true;
} else {
while ($row = pg_fetch_assoc($result)) {
$pwd = $row["DIGEST_AUTH_PASSWORD"]; //hashed password
$uid = $row["_URI"]; //uid used in other tables
}
}
}
if (!$error){
$A1 = $pwd;
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
$valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);
if ($data['response'] != $valid_response){
$error = true;
}
}
if (!$error){
return $uid;
}else{
return false;
}
}
···
On Wednesday, September 2, 2015 at 2:10:06 PM UTC-4, darub...@gmail.com wrote:
> Can someone please share the PHP working code the accepts form substitutions and put them into my sql database...
>
> Thank you
>
> On Monday, June 8, 2015 at 7:55:30 PM UTC+3, gla...@gmail.com wrote:
> > Hi, we've been trying to implement a PHP script which accepts requests from Collect and sends them to Aggregate. The reason why we are doing this is because we need to restrict which user can see which forms, something that isn't possible with Aggregate. So far, we've been able to implement the user login and the forms list through /formList. We are trying to implement form submission (/submission), but we are struggling with the PHP code. It appears that the API used to submit data is not really documented and doesn't appear to follow the OpenRosa standard described here:
> >
> > https://bitbucket.org/javarosa/javarosa/wiki/FormSubmissionAPI
> >
> > The code in Collect:
> >
> > https://code.google.com/p/opendatakit/source/browse/src/org/odk/collect/android/tasks/InstanceUploaderTask.java?repo=collect
> >
> > Seems to indicate that the communication between Collect and Aggregate relies on a 204 http response which is not mentioned in the OpenRosa standards. Also, it seems to also require a Location: in the header, which is contradictory with the "204 No Content" response. In PHP, issuing a Location in the header automatically converts the response into a 301 or 302 and ignores the 204.
> >
> > Does anybody have a functioning PHP code sample to intercept data sent from Collect?
> >
> > I tried to use other PHP code samples posted in previous threads, but they appear to only issue a 204 reponse with no Location, which doesn't appear to work in recent versions of Collect.
> >
> > Thank you very much,
> >
> > Guillaume
Maybe I'm not understanding this correctly, but if the HEAD request expects a Location back, shouldn't the response from the server be a 301 instead of a 204?
···
On Monday, June 8, 2015 at 3:37:25 PM UTC-4, Mitch wrote:
> The 204 is expected to be returned in response to a HEAD request from ODK Collect.
>
> Every submission starts with a HEAD request followed by a POST.
>
>
> This is done to (a) detect network login pages and (b) negotiate authentication credentials prior to issuing the large POST of data when submitting.
>
>
>
>
> On Mon, Jun 8, 2015 at 10:42 AM, wrote:
> I've answered my own question shortly after posting this. It looks like you can trick PHP into issuing 204 response while having a Location in the header with this simple command:
>
>
>
> header("Location: http://myserver.com/odk/",true,204);
>
>
>
> I'm now able to intercept the posted files and send them to Agggregate.
>
>
>
> Cheers,
>
>
>
> Guillaume
>
>
>
>
>
> On Monday, June 8, 2015 at 12:55:30 PM UTC-4, gla...@gmail.com wrote:
>
> > Hi, we've been trying to implement a PHP script which accepts requests from Collect and sends them to Aggregate. The reason why we are doing this is because we need to restrict which user can see which forms, something that isn't possible with Aggregate. So far, we've been able to implement the user login and the forms list through /formList. We are trying to implement form submission (/submission), but we are struggling with the PHP code. It appears that the API used to submit data is not really documented and doesn't appear to follow the OpenRosa standard described here:
>
> >
>
> > https://bitbucket.org/javarosa/javarosa/wiki/FormSubmissionAPI
>
> >
>
> > The code in Collect:
>
> >
>
> > https://code.google.com/p/opendatakit/source/browse/src/org/odk/collect/android/tasks/InstanceUploaderTask.java?repo=collect
>
> >
>
> > Seems to indicate that the communication between Collect and Aggregate relies on a 204 http response which is not mentioned in the OpenRosa standards. Also, it seems to also require a Location: in the header, which is contradictory with the "204 No Content" response. In PHP, issuing a Location in the header automatically converts the response into a 301 or 302 and ignores the 204.
>
> >
>
> > Does anybody have a functioning PHP code sample to intercept data sent from Collect?
>
> >
>
> > I tried to use other PHP code samples posted in previous threads, but they appear to only issue a 204 reponse with no Location, which doesn't appear to work in recent versions of Collect.
>
> >
>
> > Thank you very much,
>
> >
>
> > Guillaume
>
>
>
> --
>
> You received this message because you are subscribed to the Google Groups "ODK Developers" group.
>
> To unsubscribe from this group and stop receiving emails from it, send an email to opendatakit-developers+unsubscribe@googlegroups.com.
>
> For more options, visit https://groups.google.com/d/optout.
>
>
>
>
> --
>
> Mitch Sundt
> Software Engineer
> University of Washington
> mitche...@gmail.com
Here is code for a formList/index.php file that will intercept Collect submissions, validate the login and password of the user, and only show forms submitted by this user. Note that this is in PostgreSQL, not MySQL.
$error = false;
$elog = "";
if (empty($_SERVER['PHP_AUTH_DIGEST'])){ // before credentials
http_response_code(401);
header("HTTP/1.1 401 Unauthorized");
header('Content-Type: text/xml; charset=utf-8');
header('WWW-Authenticate: Digest realm="INSERT YOUR REALM HERE",qop="auth",nonce="'.uniqid().'",opaque="'.md5('INSERT YOUR REALM HERE').'"');
header('"HTTP_X_OPENROSA_VERSION": "1.0"');
header('X-OpenRosa-Version:1.0');
// query db for hashed password for given username
if (!$error){
$name = pg_escape_literal($name);
$query = 'SELECT * FROM odk_prod._registered_users WHERE "LOCAL_USERNAME" = '.$name.' AND "IS_REMOVED" = FALSE';
$result = pg_query($con_pg, $query);
if (!$result) {
$error = true;
} else {
while ($row = pg_fetch_assoc($result)) {
$pwd = $row["DIGEST_AUTH_PASSWORD"]; //hashed password
$uid = $row["_URI"]; //uid used in other tables
}
}
}
if (!$error){
$A1 = $pwd;
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
$valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);
if ($data['response'] != $valid_response){
$error = true;
}
}
if (!$error){
return $uid;
}else{
return false;
}
}
Can someone please share the PHP working code the accepts form substitutions and put them into my sql database...
Thank you
Hi, we've been trying to implement a PHP script which accepts requests from Collect and sends them to Aggregate. The reason why we are doing this is because we need to restrict which user can see which forms, something that isn't possible with Aggregate. So far, we've been able to implement the user login and the forms list through /formList. We are trying to implement form submission (/submission), but we are struggling with the PHP code. It appears that the API used to submit data is not really documented and doesn't appear to follow the OpenRosa standard described here:
Seems to indicate that the communication between Collect and Aggregate relies on a 204 http response which is not mentioned in the OpenRosa standards. Also, it seems to also require a Location: in the header, which is contradictory with the "204 No Content" response. In PHP, issuing a Location in the header automatically converts the response into a 301 or 302 and ignores the 204.
Hi ...has this worked for anyone?
Does anybody have a functioning PHP code sample to intercept data sent from Collect?
I tried to use other PHP code samples posted in previous threads, but they appear to only issue a 204 reponse with no Location, which doesn't appear to work in recent versions of Collect.
Thank you very much,
Guillaume
···
On Wednesday, September 2, 2015 at 9:59:20 PM UTC+3, gla...@gmail.com wrote:
> On Wednesday, September 2, 2015 at 2:10:06 PM UTC-4, darub...@gmail.com wrote:
> > On Monday, June 8, 2015 at 7:55:30 PM UTC+3, gla...@gmail.com wrote:
The 201/204 and the Location header were both attempts to detect Network
login screens. The Location header was the first attempt at this.
The current ODK Collect makes the Location header optional -- if supplied,
it can be used to redirect the submission path (/submission) to a different
path on the same server (or to a different scheme (e.g., https://); ODK
Collect does not allow a server to redirect to a different server URL.
ODK Aggregate always returns the .../submission URL as the Location, even
on a POST (and ODK Collect only processes the Location header on the HEAD
request). Returning this Location in response to a POST is not
expected/conformant REST behavior (it should return the download URL for
accessing the posted submission).
We then switched to the non-standard 201 return code to indicate a
successful interaction with the server and added the HEAD request to
confirm the scheme and authentication before the POST (so we never send
data over http unless the server accepts that, and we always have valid
authentication before sending large payloads to the server).
The question then became what to return from the initial HEAD request. We
can't determine the appropriate response from a HEAD request because the
response code is dependent upon the entity, and the HEAD request doesn't
contain one. So we settled on the 204 response, as the normal 201 response
does have an entity body which contains an XML response entity holding
information about the submission.
···
On Mon, Jun 8, 2015 at 12:51 PM, wrote:
Maybe I'm not understanding this correctly, but if the HEAD request
expects a Location back, shouldn't the response from the server be a 301
instead of a 204?
On Monday, June 8, 2015 at 3:37:25 PM UTC-4, Mitch wrote:
The 204 is expected to be returned in response to a HEAD request from
ODK Collect.
Every submission starts with a HEAD request followed by a POST.
This is done to (a) detect network login pages and (b) negotiate
authentication credentials prior to issuing the large POST of data when
submitting.
On Mon, Jun 8, 2015 at 10:42 AM, gla...@gmail.com wrote:
I've answered my own question shortly after posting this. It looks like
you can trick PHP into issuing 204 response while having a Location in the
header with this simple command:
I'm now able to intercept the posted files and send them to Agggregate.
Cheers,
Guillaume
On Monday, June 8, 2015 at 12:55:30 PM UTC-4, gla...@gmail.com wrote:
Hi, we've been trying to implement a PHP script which accepts requests
from Collect and sends them to Aggregate. The reason why we are doing this
is because we need to restrict which user can see which forms, something
that isn't possible with Aggregate. So far, we've been able to implement
the user login and the forms list through /formList. We are trying to
implement form submission (/submission), but we are struggling with the PHP
code. It appears that the API used to submit data is not really documented
and doesn't appear to follow the OpenRosa standard described here:
Seems to indicate that the communication between Collect and Aggregate
relies on a 204 http response which is not mentioned in the OpenRosa
standards. Also, it seems to also require a Location: in the header, which
is contradictory with the "204 No Content" response. In PHP, issuing a
Location in the header automatically converts the response into a 301 or
302 and ignores the 204.
Does anybody have a functioning PHP code sample to intercept data sent
from Collect?
I tried to use other PHP code samples posted in previous threads, but
they appear to only issue a 204 reponse with no Location, which doesn't
appear to work in recent versions of Collect.
Thank you very much,
Guillaume
--
You received this message because you are subscribed to the Google
Groups "ODK Developers" group.
···
On Wednesday, February 3, 2016 at 1:24:35 PM UTC-5, krcsde...@gmail.com wrote:
> On Wednesday, September 2, 2015 at 9:59:20 PM UTC+3, gla...@gmail.com wrote:
> > Here is code for a formList/index.php file that will intercept Collect submissions, validate the login and password of the user, and only show forms submitted by this user. Note that this is in PostgreSQL, not MySQL.
> >
> > $error = false;
> > $elog = "";
> >
> > if (empty($_SERVER['PHP_AUTH_DIGEST'])){ // before credentials
> >
> > http_response_code(401);
> > header("HTTP/1.1 401 Unauthorized");
> > header('Content-Type: text/xml; charset=utf-8');
> > header('WWW-Authenticate: Digest realm="**INSERT YOUR REALM HERE**",qop="auth",nonce="'.uniqid().'",opaque="'.md5('**INSERT YOUR REALM HERE**').'"');
> > header('"HTTP_X_OPENROSA_VERSION": "1.0"');
> > header('X-OpenRosa-Version:1.0');
> >
> > } else { // after credentials
> >
> > header('Content-Type: text/xml; charset=utf-8');
> > header('"HTTP_X_OPENROSA_VERSION": "1.0"');
> > header('X-OpenRosa-Version:1.0');
> >
> > $uid=check_user_pass();
> > if ($uid!==false){
> > echo '';
> > $uid = pg_escape_literal($uid);
> > $query = 'SELECT * FROM odk_prod._form_info WHERE "_CREATOR_URI_USER" = '.$uid.' AND "_IS_COMPLETE" = TRUE';
> > $result = pg_query($con_pg, $query);
> > if (!$result) {
> > $error = true;
> > } else {
> > while ($row = pg_fetch_assoc($result)) {
> > $form = $row["FORM_ID"];
> > $query = 'SELECT "FORM_NAME", "ROOT_ELEMENT_MODEL_VERSION" FROM odk_prod._form_info_fileset WHERE "_TOP_LEVEL_AURI" = \''.$row['_URI'].'\'';
> > $result_ref = pg_query($con_pg,$query);
> > $row_ref=pg_fetch_assoc($result_ref);
> > echo '';
> > echo ''.$form.'';
> > echo ''.$row_ref['FORM_NAME'].'';
> > echo ''.$row_ref['ROOT_ELEMENT_MODEL_VERSION'].'';
> > echo ''.$row_ref['ROOT_ELEMENT_MODEL_VERSION'].'';
> > echo ''.$row['_URI'].'';
> > echo 'http://quebio.ca/odk/formXML/?formId='.$form.'';
> > $query = 'SELECT * FROM odk_prod._form_info_manifest_bin WHERE "_TOP_LEVEL_AURI" = \''.$row['_URI'].'\'';
> > $result2 = pg_query($con_pg, $query);
> > if (pg_num_rows($result2)>0){
> > echo 'http://**YOUR_SERVER_ADDRESS**/formList/xformsManifest.php?formId='.$form.'';
> > }
> > echo '';
> > }
> > }
> > echo '';
> > }
> > }
> >
> >
> > function check_user_pass() {
> > $data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST']);
> > $name = $data['username'];
> > $error=false;
> > // double check connection
> > if (!$con_pg) {
> > $error = true;
> > }
> >
> > // query db for hashed password for given username
> > if (!$error){
> > $name = pg_escape_literal($name);
> > $query = 'SELECT * FROM odk_prod._registered_users WHERE "LOCAL_USERNAME" = '.$name.' AND "IS_REMOVED" = FALSE';
> > $result = pg_query($con_pg, $query);
> > if (!$result) {
> > $error = true;
> > } else {
> > while ($row = pg_fetch_assoc($result)) {
> > $pwd = $row["DIGEST_AUTH_PASSWORD"]; //hashed password
> > $uid = $row["_URI"]; //uid used in other tables
> > }
> > }
> > }
> >
> > if (!$error){
> > $A1 = $pwd;
> > $A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
> > $valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);
> > if ($data['response'] != $valid_response){
> > $error = true;
> > }
> > }
> > if (!$error){
> > return $uid;
> > }else{
> > return false;
> > }
> > }
> >
> >
> >
> > On Wednesday, September 2, 2015 at 2:10:06 PM UTC-4, darub...@gmail.com wrote:
> > > Can someone please share the PHP working code the accepts form substitutions and put them into my sql database...
> > >
> > > Thank you
> > >
> > > On Monday, June 8, 2015 at 7:55:30 PM UTC+3, gla...@gmail.com wrote:
> > > > Hi, we've been trying to implement a PHP script which accepts requests from Collect and sends them to Aggregate. The reason why we are doing this is because we need to restrict which user can see which forms, something that isn't possible with Aggregate. So far, we've been able to implement the user login and the forms list through /formList. We are trying to implement form submission (/submission), but we are struggling with the PHP code. It appears that the API used to submit data is not really documented and doesn't appear to follow the OpenRosa standard described here:
> > > >
> > > > https://bitbucket.org/javarosa/javarosa/wiki/FormSubmissionAPI
> > > >
> > > > The code in Collect:
> > > >
> > > > https://code.google.com/p/opendatakit/source/browse/src/org/odk/collect/android/tasks/InstanceUploaderTask.java?repo=collect
> > > >
> > > > Seems to indicate that the communication between Collect and Aggregate relies on a 204 http response which is not mentioned in the OpenRosa standards. Also, it seems to also require a Location: in the header, which is contradictory with the "204 No Content" response. In PHP, issuing a Location in the header automatically converts the response into a 301 or 302 and ignores the 204.
> > > > Hi ...has this worked for anyone?
>
>
>
> > > > Does anybody have a functioning PHP code sample to intercept data sent from Collect?
> > > >
> > > > I tried to use other PHP code samples posted in previous threads, but they appear to only issue a 204 reponse with no Location, which doesn't appear to work in recent versions of Collect.
> > > >
> > > > Thank you very much,
> > > >
> > > > Guillaume
And the Location redirection doesn't actually get exercised in ODK Collect
when connecting to ODK Aggregate, as the server is using the Spring
framework to handle scheme and authentication negotiations, so we never hit
our servlets until that is handled in the standard (30x) ways.
···
On Mon, Jun 8, 2015 at 3:33 PM, Mitch Sundt wrote:
Here's the history on why:
The 201/204 and the Location header were both attempts to detect Network
login screens. The Location header was the first attempt at this.
The current ODK Collect makes the Location header optional -- if supplied,
it can be used to redirect the submission path (/submission) to a different
path on the same server (or to a different scheme (e.g., https://); ODK
Collect does not allow a server to redirect to a different server URL.
ODK Aggregate always returns the .../submission URL as the Location, even
on a POST (and ODK Collect only processes the Location header on the HEAD
request). Returning this Location in response to a POST is not
expected/conformant REST behavior (it should return the download URL for
accessing the posted submission).
We then switched to the non-standard 201 return code to indicate a
successful interaction with the server and added the HEAD request to
confirm the scheme and authentication before the POST (so we never send
data over http unless the server accepts that, and we always have valid
authentication before sending large payloads to the server).
The question then became what to return from the initial HEAD request. We
can't determine the appropriate response from a HEAD request because the
response code is dependent upon the entity, and the HEAD request doesn't
contain one. So we settled on the 204 response, as the normal 201 response
does have an entity body which contains an XML response entity holding
information about the submission.
Maybe I'm not understanding this correctly, but if the HEAD request
expects a Location back, shouldn't the response from the server be a 301
instead of a 204?
On Monday, June 8, 2015 at 3:37:25 PM UTC-4, Mitch wrote:
The 204 is expected to be returned in response to a HEAD request from
ODK Collect.
Every submission starts with a HEAD request followed by a POST.
This is done to (a) detect network login pages and (b) negotiate
authentication credentials prior to issuing the large POST of data when
submitting.
On Mon, Jun 8, 2015 at 10:42 AM, gla...@gmail.com wrote:
I've answered my own question shortly after posting this. It looks like
you can trick PHP into issuing 204 response while having a Location in the
header with this simple command:
I'm now able to intercept the posted files and send them to Agggregate.
Cheers,
Guillaume
On Monday, June 8, 2015 at 12:55:30 PM UTC-4, gla...@gmail.com wrote:
Hi, we've been trying to implement a PHP script which accepts
requests from Collect and sends them to Aggregate. The reason why we are
doing this is because we need to restrict which user can see which forms,
something that isn't possible with Aggregate. So far, we've been able to
implement the user login and the forms list through /formList. We are
trying to implement form submission (/submission), but we are struggling
with the PHP code. It appears that the API used to submit data is not
really documented and doesn't appear to follow the OpenRosa standard
described here:
Seems to indicate that the communication between Collect and
Aggregate relies on a 204 http response which is not mentioned in the
OpenRosa standards. Also, it seems to also require a Location: in the
header, which is contradictory with the "204 No Content" response. In PHP,
issuing a Location in the header automatically converts the response into a
301 or 302 and ignores the 204.
Does anybody have a functioning PHP code sample to intercept data
sent from Collect?
I tried to use other PHP code samples posted in previous threads, but
they appear to only issue a 204 reponse with no Location, which doesn't
appear to work in recent versions of Collect.
Thank you very much,
Guillaume
--
You received this message because you are subscribed to the Google
Groups "ODK Developers" group.
Thanks...
do I need only this code or you can share the whole php project.
···
On Wed, Feb 3, 2016 at 9:33 PM, wrote:
It works for us...
On Wednesday, February 3, 2016 at 1:24:35 PM UTC-5, krcsde...@gmail.com wrote:
On Wednesday, September 2, 2015 at 9:59:20 PM UTC+3, gla...@gmail.com wrote:
Here is code for a formList/index.php file that will intercept Collect
submissions, validate the login and password of the user, and only show
forms submitted by this user. Note that this is in PostgreSQL, not MySQL.
$error = false;
$elog = "";
if (empty($_SERVER['PHP_AUTH_DIGEST'])){ // before credentials
// query db for hashed password for given username
if (!$error){
$name = pg_escape_literal($name);
$query = 'SELECT * FROM odk_prod._registered_users WHERE
"LOCAL_USERNAME" = '.$name.' AND "IS_REMOVED" = FALSE';
$result = pg_query($con_pg, $query);
if (!$result) {
$error = true;
} else {
while ($row = pg_fetch_assoc($result)) {
$pwd = $row["DIGEST_AUTH_PASSWORD"]; //hashed password
$uid = $row["_URI"]; //uid used in other tables
}
}
}
if (!$error){
$A1 = $pwd;
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
$valid_response =
if ($data['response'] != $valid_response){
$error = true;
}
}
if (!$error){
return $uid;
}else{
return false;
}
}
On Wednesday, September 2, 2015 at 2:10:06 PM UTC-4, darub...@gmail.com wrote:
Can someone please share the PHP working code the accepts form
substitutions and put them into my sql database...
Thank you
On Monday, June 8, 2015 at 7:55:30 PM UTC+3, gla...@gmail.com wrote:
Hi, we've been trying to implement a PHP script which accepts
requests from Collect and sends them to Aggregate. The reason why we are
doing this is because we need to restrict which user can see which forms,
something that isn't possible with Aggregate. So far, we've been able to
implement the user login and the forms list through /formList. We are
trying to implement form submission (/submission), but we are struggling
with the PHP code. It appears that the API used to submit data is not
really documented and doesn't appear to follow the OpenRosa standard
described here:
Seems to indicate that the communication between Collect and
Aggregate relies on a 204 http response which is not mentioned in the
OpenRosa standards. Also, it seems to also require a Location: in the
header, which is contradictory with the "204 No Content" response. In PHP,
issuing a Location in the header automatically converts the response into a
301 or 302 and ignores the 204.
Hi ...has this worked for anyone?
Does anybody have a functioning PHP code sample to intercept data
sent from Collect?
I tried to use other PHP code samples posted in previous threads,
but they appear to only issue a 204 reponse with no Location, which doesn't
appear to work in recent versions of Collect.
"The current ODK Collect makes the Location header optional -- if supplied, it can be used to redirect the submission path (/submission) to a different path on the same server (or to a different scheme (e.g., https://);"
I was lead to think otherwise when seeing the piece of code that handles the response:
Anyway, I've sorted out a way to handle this with PHP.
Thanks again for your time and response.
Guillaume
···
On Monday, June 8, 2015 at 6:49:21 PM UTC-4, Mitch wrote:
> And the Location redirection doesn't actually get exercised in ODK Collect when connecting to ODK Aggregate, as the server is using the Spring framework to handle scheme and authentication negotiations, so we never hit our servlets until that is handled in the standard (30x) ways.
>
>
>
>
> On Mon, Jun 8, 2015 at 3:33 PM, Mitch Sundt wrote:
>
> Here's the history on why:
>
> The 201/204 and the Location header were both attempts to detect Network login screens. The Location header was the first attempt at this.
>
>
> The current ODK Collect makes the Location header optional -- if supplied, it can be used to redirect the submission path (/submission) to a different path on the same server (or to a different scheme (e.g., https://); ODK Collect does not allow a server to redirect to a different server URL.
>
>
> ODK Aggregate always returns the .../submission URL as the Location, even on a POST (and ODK Collect only processes the Location header on the HEAD request). Returning this Location in response to a POST is not expected/conformant REST behavior (it should return the download URL for accessing the posted submission).
>
>
>
> We then switched to the non-standard 201 return code to indicate a successful interaction with the server and added the HEAD request to confirm the scheme and authentication before the POST (so we never send data over http unless the server accepts that, and we always have valid authentication before sending large payloads to the server).
>
> The question then became what to return from the initial HEAD request. We can't determine the appropriate response from a HEAD request because the response code is dependent upon the entity, and the HEAD request doesn't contain one. So we settled on the 204 response, as the normal 201 response does have an entity body which contains an XML response entity holding information about the submission.
>
>
>
>
>
>
>
> On Mon, Jun 8, 2015 at 12:51 PM, wrote:
> Maybe I'm not understanding this correctly, but if the HEAD request expects a Location back, shouldn't the response from the server be a 301 instead of a 204?
>
>
>
>
>
>
>
> On Monday, June 8, 2015 at 3:37:25 PM UTC-4, Mitch wrote:
>
> > The 204 is expected to be returned in response to a HEAD request from ODK Collect.
>
> >
>
> > Every submission starts with a HEAD request followed by a POST.
>
> >
>
> >
>
> > This is done to (a) detect network login pages and (b) negotiate authentication credentials prior to issuing the large POST of data when submitting.
>
> >
>
> >
>
> >
>
> >
>
> > On Mon, Jun 8, 2015 at 10:42 AM, wrote:
>
> > I've answered my own question shortly after posting this. It looks like you can trick PHP into issuing 204 response while having a Location in the header with this simple command:
>
> >
>
> >
>
> >
>
> > header("Location: http://myserver.com/odk/",true,204);
>
> >
>
> >
>
> >
>
> > I'm now able to intercept the posted files and send them to Agggregate.
>
> >
>
> >
>
> >
>
> > Cheers,
>
> >
>
> >
>
> >
>
> > Guillaume
>
> >
>
> >
>
> >
>
> >
>
> >
>
> > On Monday, June 8, 2015 at 12:55:30 PM UTC-4, gla...@gmail.com wrote:
>
> >
>
> > > Hi, we've been trying to implement a PHP script which accepts requests from Collect and sends them to Aggregate. The reason why we are doing this is because we need to restrict which user can see which forms, something that isn't possible with Aggregate. So far, we've been able to implement the user login and the forms list through /formList. We are trying to implement form submission (/submission), but we are struggling with the PHP code. It appears that the API used to submit data is not really documented and doesn't appear to follow the OpenRosa standard described here:
>
> >
>
> > >
>
> >
>
> > > https://bitbucket.org/javarosa/javarosa/wiki/FormSubmissionAPI
>
> >
>
> > >
>
> >
>
> > > The code in Collect:
>
> >
>
> > >
>
> >
>
> > > https://code.google.com/p/opendatakit/source/browse/src/org/odk/collect/android/tasks/InstanceUploaderTask.java?repo=collect
>
> >
>
> > >
>
> >
>
> > > Seems to indicate that the communication between Collect and Aggregate relies on a 204 http response which is not mentioned in the OpenRosa standards. Also, it seems to also require a Location: in the header, which is contradictory with the "204 No Content" response. In PHP, issuing a Location in the header automatically converts the response into a 301 or 302 and ignores the 204.
>
> >
>
> > >
>
> >
>
> > > Does anybody have a functioning PHP code sample to intercept data sent from Collect?
>
> >
>
> > >
>
> >
>
> > > I tried to use other PHP code samples posted in previous threads, but they appear to only issue a 204 reponse with no Location, which doesn't appear to work in recent versions of Collect.
>
> >
>
> > >
>
> >
>
> > > Thank you very much,
>
> >
>
> > >
>
> >
>
> > > Guillaume
>
> >
>
> >
>
> >
>
> > --
>
> >
>
> > You received this message because you are subscribed to the Google Groups "ODK Developers" group.
>
> >
>
> > To unsubscribe from this group and stop receiving emails from it, send an email to opendatakit-developers+unsubscribe@googlegroups.com.
>
> >
>
> > For more options, visit https://groups.google.com/d/optout.
>
> >
>
> >
>
> >
>
> >
>
> > --
>
> >
>
> > Mitch Sundt
>
> > Software Engineer
>
> > University of Washington
>
> > mitche...@gmail.com
>
>
>
>
>
> --
>
> You received this message because you are subscribed to the Google Groups "ODK Developers" group.
>
> To unsubscribe from this group and stop receiving emails from it, send an email to opendatakit-developers+unsubscribe@googlegroups.com.
>
> For more options, visit https://groups.google.com/d/optout.
>
>
>
>
> --
>
>
>
> Mitch Sundt
> Software Engineer
> University of Washington
> mitche...@gmail.com
>
>
>
>
> --
>
> Mitch Sundt
> Software Engineer
> University of Washington
> mitche...@gmail.com