Problem Connecting to Web Service

October 28, 2012 - 7:10am #1

I might be doing something completely wrong as I've not much experience with these kind of things, so please point out any mistakes you might notice.

I'm trying to see if I can connect to the VWS, so I've decided to start with a simple GET on /targets.

However, all I get is the following error:
Exception: "Unable to connect to the remote server"
InnerException: "No connection could be made because the target machine actively refused it 66.109.101.160:80"

Here is my code:

 

MD5 md5 = MD5.Create();
HMACSHA1 hmacsha1 = new HMACSHA1();
hmacsha1.Key = Encoding.Unicode.GetBytes(Properties.Resources.ServerSecretKey);

string requestPath = Properties.Resources.deploymentBaseURL + "/targets";
           
string httpVerb = "GET";
var contentMD5bytes = md5.ComputeHash(Encoding.Unicode.GetBytes(""));
string contentMD5 = BitConverter.ToString(contentMD5bytes).Replace("-","");
string contentType = "";
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
string date = DateTime.UtcNow.ToString("ddd, dd MMM yyy HH:mm:ss") + " GMT";
                      
string StringToSign = String.Format("{0}\n{1}\n{2}\n{3}\n{4}", httpVerb, contentMD5, contentType, date ,requestPath);
// HTTP-Verb, Content-MD5, Content-Type, Date, Request-Path;

var stringToSignBytes = Encoding.Unicode.GetBytes(StringToSign);
var stringToSignHash = hmacsha1.ComputeHash(stringToSignBytes);
string Signature = Convert.ToBase64String(stringToSignHash);
           
WebRequest request = WebRequest.Create(requestPath);
        
request.Headers.Add("Authorization",String.Format("VWS {0}:{1}", Properties.Resources.ServerAccessKey, Signature));
var response = request.GetResponse();

 

Where:

Any and all help much appreciated,
Nathan

Problem Connecting to Web Service

February 5, 2013 - 1:48am #35

Hi thanks for this. I was scratching my head over a minute problem in my code for ages until I read this.

My posts here may help anyone trying to do this in unity:

https://developer.vuforia.com/forum/cloud-recognition/vws-requests-c-unity-authentication#comment-2021210

Cheers

Tom

Problem Connecting to Web Service

February 5, 2013 - 1:25am #34

Thanks so much for this - Solved a mojor problem for me.

 

Regards

Tom

Problem Connecting to Web Service

February 4, 2013 - 6:29pm #33

Thanks

Problem Connecting to Web Service

February 2, 2013 - 12:43pm #32

Thanks for the update lukiller.

Problem Connecting to Web Service

February 2, 2013 - 5:07am #31

You are right. I also changed the date assignment, instead of adding +3 (because of my time zone), now I am using this way:

 

string date = string.Format("{0:r}", DateTime.Now.ToUniversalTime());

 

Problem Connecting to Web Service

February 1, 2013 - 12:34pm #30

 

Your code is great ! it helped me a lot to comunicate unity with vuforia service
 
By the way, you can  set the active_flag property changing the declaration in PostNewTrackableRequest class to   "public bool active_flag;" and assign it with 'false' or 'true' values (0 or 1 wont work in c#).

Sounds great!  I'm sure your

January 15, 2013 - 11:10pm #29

Sounds great!  I'm sure your code snippet (with the little modifications you mentioned) will be useful to many others who use C# as well.

It works!

January 15, 2013 - 2:10pm #28

I discovered the problem, the ToString("X2") format used to generate the string for the MD5, has to be in lowercase -> ToString("x2").

I also removed the active_flag property from the PostNewTrackableRequest class.

Now the code is C# is finally working!!!

Yes, if anyone has done the

January 15, 2013 - 5:31am #27

Yes, if anyone has done the same in C# he is welcome to share.

@lukiller: have you tried comparing your implementation with the reference Java samples ?

one thing you could try is to print out the various strings produced by your implementation (for instance the Json request body) and check against the Java samples (also printing out the intermediate strings...) to see if there are any difference;

(401) Unauthorized

January 15, 2013 - 4:51am #26

Hi, I can get the list of targets from my cloud database with no problems, but I still cannot post a new target. It always returns the error 401 Unauthorized. This is my full code, it may have parts I got from this forum:

 

 

    public class VWSConnection
    {
        private static string access_key = "29c69dee45700a1bbc018b9bd70158b14844fd2e";
        private static string secret_key = "77ec8c649bb66fb97876644e16c9b51278fb7b80";
        private static string url = @"https://vws.vuforia.com";
        private static string targetName = "MyTarget";
        private static string imageLocation = @"/blah/blah/blah/myFile.jpg";
        private static byte[] requestBytesArray;
 
        private static void PostNewTargets()
        {
            WebResponse response = null;
 
            try
            {
                string requestPath = "/targets";
                string serviceURI = url + requestPath;
                string httpAction = "POST";
                string contentType = "application/json";
                string date = string.Format("{0:r}", DateTime.Now.AddHours(+3)); // I added 3 because my location is GMT-3
 
                var imageFile = File.Open(imageLocation, FileMode.Open);
                byte[] image = StreamUtils.StreamToByteArray(imageFile);
 
                string metadataStr = "Vuforia test metadata";
                byte[] metadata = System.Text.ASCIIEncoding.ASCII.GetBytes(metadataStr);
                PostNewTrackableRequest model = new PostNewTrackableRequest();
                model.name = targetName;
                model.width = "64.0";
                model.image = System.Convert.ToBase64String(image);
                model.active_flag = "1";
                model.application_metadata = System.Convert.ToBase64String(metadata);
                string requestBody = JsonWriter.Serialize(model);
 
                HttpWebRequest httpWReq = (HttpWebRequest)HttpWebRequest.Create(serviceURI);
                httpWReq.Method = httpAction;
                MethodInfo priMethod = httpWReq.Headers.GetType().GetMethod("AddWithoutValidate", BindingFlags.Instance | BindingFlags.NonPublic);
                priMethod.Invoke(httpWReq.Headers, new[] { "Date", date });
                httpWReq.ContentType = contentType;
 
                MD5 md5 = MD5.Create();
                var contentMD5bytes = md5.ComputeHash(System.Text.Encoding.ASCII.GetBytes(requestBody));
                System.Text.StringBuilder sb = new System.Text.StringBuilder();
                for (int i = 0; i < contentMD5bytes.Length; i++)
                {
                    sb.Append(contentMD5bytes[i].ToString("X2"));
                }
 
                string contentMD5 = sb.ToString();
 
                string stringToSign = string.Format("{0}\n{1}\n{2}\n{3}\n{4}", httpAction, contentMD5, contentType, date, requestPath);
 
                HMACSHA1 sha1 = new HMACSHA1(System.Text.Encoding.ASCII.GetBytes(secret_key));
                byte[] sha1Bytes = Encoding.ASCII.GetBytes(stringToSign);
                MemoryStream stream = new MemoryStream(sha1Bytes);
                byte[] sha1Hash = sha1.ComputeHash(stream);
                string signature = System.Convert.ToBase64String(sha1Hash);
                httpWReq.Headers.Add("Authorization", string.Format("VWS {0}:{1}", access_key, signature));
 
                var streamWriter = httpWReq.GetRequestStream();
                byte[] buffer = System.Text.Encoding.ASCII.GetBytes(requestBody);
                requestBytesArray = buffer;
                streamWriter.Write(buffer, 0, buffer.Length);
                streamWriter.Flush();
                streamWriter.Close();
 
                response = httpWReq.GetResponse();
 
                Stream receiveStream = response.GetResponseStream();
                StreamReader sr = new StreamReader(receiveStream, System.Text.Encoding.UTF8);
                string responseData = sr.ReadToEnd();
                response.Close();
                sr.Close();
                GetTargetsResponse result = JsonReader.Deserialize<GetTargetsResponse>(responseData);
                Debug.Log("Transaction result: " + result.result_code);
                Debug.Log("Transaction ID: " + result.transaction_id);
            }
            catch (Exception ex)
            {
                Debug.Log(string.Format("ERROR: {0}", ex.Message));
            }
        }
    }
 
    public class PostNewTrackableRequest
    {
        public string name;
        public string width;
        public string image;
        public string active_flag;
        public string application_metadata;
    }
 

It will be apreciated if anyone can help me with this.

Thanks.

For anyone interested in the

January 15, 2013 - 1:09am #25

For anyone interested in the official CloudReco VWS API samples, here is the link to the page on our web portal:

https://developer.vuforia.com/resources/dev-guide/managing-targets-cloud-database-using-developer-api

The samples are at the bottom of the page (just click on "VWS Sample Code" to download the zip package).

 

For the C# samples made by Nathan, it would be great if Nathan could share a valid link again...

Hi, can you post this sample

January 10, 2013 - 3:36pm #24

Hi, can you post the c# sample again, the link seems to be broken. Thanks!

They'll be available very

December 18, 2012 - 2:37pm #23

They'll be available very soon. I'll post a link.

Hello, Could you tell me

December 18, 2012 - 8:56am #22

Hello,

Could you tell me where can i find examples in java?

Best Regards

Alojzy

Problem Connecting to Web Service

November 7, 2012 - 7:32am #21

That's really great, thanks!

Problem Connecting to Web Service

November 7, 2012 - 6:39am #20

The code to a functional C# Winforms application for simple VWS Management can be found here:
https://ar.qualcomm.at/content/sample-cnet-vws-management-application

Problem Connecting to Web Service

November 1, 2012 - 2:30pm #19

@Duane: thanks for highlighting it, it sounds like a little detail, but it is a very important one, indeed, the month must be in three-letter format (e.g. "Apr" instead of "April")

 

Problem Connecting to Web Service

November 1, 2012 - 12:33am #18

I took your edited code as it is... and it didnt work for me.. 401

Problem Connecting to Web Service

October 31, 2012 - 3:42pm #17

AlessandroB wrote:

Secondly, I would suggest to Log/print out the value of your Date, just to be sure that it matches this format:

Mon, 23 April 2012 12:45:19 GMT

Note to lurkers on this thread trying to figure out their signature problems - this should instead be "Mon, 23 Apr 2012 12:45:19 GMT" (note the short month name).

Problem Connecting to Web Service

October 31, 2012 - 2:28pm #16

Yes please share your snippets  ;)

Problem Connecting to Web Service

October 31, 2012 - 9:03am #15

@Nathan: Sounds good! It will be great to have your updated code snippets shared here.

Problem Connecting to Web Service

October 31, 2012 - 3:41am #14

Okay,
I've found that the culprit was incorrect encoding (For some reason I used Unicode instead of ASCII).

I now got it to work and edited the code in the original code to reflect the required changes.

I'll now procees to writing a small management suite which I will share as soon as it's done.

 

Thanks for the help,
Nathan

Problem Connecting to Web Service

October 31, 2012 - 2:06am #13

Hey, i also got the java examples and it did work!

i am trying to take the postnewtarget and make it work using c#

i'm getting also error 401.

if someone can make it work in c# i will be very happy to know how.

 

About the Date header i found a walkaround to override the Date using:

 DateTime dt = DateTime.Now;

            String dtString = String.Format("{0:r}", dt);  //Tue, 30 Oct 2012 11:17:19 GMT

            MethodInfo priMethod = httpWReq.Headers.GetType().GetMethod("AddWithoutValidate", BindingFlags.Instance | BindingFlags.NonPublic);

            priMethod.Invoke(httpWReq.Headers, new[] { "Date", dtString });

 

I think the issue is with one of the md5 and all this encoding.. pretty sure i'm doing sometihng wrong there..

can't understand why the ahutentication is so complex :p

 

i uploaded the code, here is the url:

https://dl.dropbox.com/u/13431688/visualsearch.rar

 

Problem Connecting to Web Service

October 30, 2012 - 6:07am #12

That sounds good! It would be really great indeed, if you can share your C# code here when you manage to make it work.

Problem Connecting to Web Service

October 30, 2012 - 5:58am #11

Thanks :)

I got the java code samples from David and I got them to work.

I'll update the code in this post when I have figured out the problem with it.

Problem Connecting to Web Service

October 30, 2012 - 5:30am #10

@Nathan: I tested the access with your keys and they work fine; meanwhile you can follow-up with DavidB to get some sample code that works (see previous message).

 

Problem Connecting to Web Service

October 29, 2012 - 10:04am #9

Alessandro:

Changing the header as you suggest is impossible (it causes an exception).
But I did make sure that the Date value saved in the Date Header and the Date field of the StringToSign are identical - still 401.

Problem Connecting to Web Service

October 29, 2012 - 9:53am #8

@Nathan - PM me if you'd like a set of Java samples that demonstrate the headers that are needed, and their format.

Problem Connecting to Web Service

October 29, 2012 - 9:50am #7

Meanwhile, I just noticed that you set the date in your request by calling:

request.Date = Date.UtcNow;

That also sounds like a potential issue, as there the date format will not be consistent;

so, you may want to try something like this for instance:

request.Headers.Add("Date", DateTime.UtcNow.ToString("ddd, dd MMM yyy HH:mm:ss") + " GMT");

so that the date format is still consistent with the rest.

 

Problem Connecting to Web Service

October 29, 2012 - 9:01am #6

Hi, I see you edited the original post, updating the error code you have which is now:

The remote server returned an error: (401) Unauthorized

This might mean some problem with your accessKey and/or secretKey;

if you could provide them, we could make a test here to check what goes wrong (you could PM me with those);

as far as your code is concerned, it really looks ok.

A.

Problem Connecting to Web Service

October 29, 2012 - 8:37am #5

Hey Alessandro,

Thanks for the reply.

The data inside the HttpWebRequest Header for the Date field is "Mon, 29 Oct 2012 15:29:32 GMT" so I think this is ok.

I've changed the request-path to what you've advised but I'm still getting the same (401) error.

I'll update the code now to reflect the changes.

Thanks

EDIT:
If possible, I would be very happy to receive a working piece of code or some sample application for uploading targets to TMS.

Problem Connecting to Web Service

October 29, 2012 - 8:24am #4

Hi, if you look at your code, 

string StringToSign = String.Format("{0}\n{1}\n{2}\n{3}\n{4}", httpVerb, contentMD5, contentType, date ,requestPath); 

the requestPath you are using there is the full URI (i.e. including the baseDeploymentURL);

on the other hand, when building the StringToSign, as argument {4} you should only include the "path" of your URI (e.g. "/targets"), not the entire URI (as you seem to be doing) i.e. not "https://vws.vuforia.com/targets", but just "/targets"

That is already a possible issue.

Secondly, I would suggest to Log/print out the value of your Date, just to be sure that it matches this format:

Mon, 23 April 2012 12:45:19 GMT

(probably that should be the case already, but always better to double check, you never know...)



 



Problem Connecting to Web Service

October 29, 2012 - 4:51am #3

You are correct.
I, indeed, forgot to add the date to the header.

I added the date to the header (observe the change in the original post) but I'm still getting the same (401) error.

Thanks

Problem Connecting to Web Service

October 29, 2012 - 2:52am #2

Are you passing the date header as one of your http headers -- it does not look that way from your code.

Log in or register to post comments