URL encode char*

I have the following function which sends text to a php script. But the php script only gets the first word of the sentence.

How do I convert the LogTxt to something that the php will receive as a sentence ?

eg : sending : this is a line, of data, 1,2,3

void LogItWebC(char* LogTxt){

  if (client.connect(myserver, 80)) {
    Serial.println("connected");
    client.print("GET http://www.AAA.co.za/serveit.php?data=");
    client.print(LogTxt);
    client.println(" HTTP/1.1");
    client.println("Host: www.AAA.co.za");
    client.println();
    delay(250);
    client.stop();
    Serial.println(LogTxt);
    Serial.println("disconnected");
    Serial.println("==================");
  } 
  else {
    Serial.println("connection failed");
    Serial.println("==================");
  }
}

You need to replace certain characters, like space, with different characters. Space becomes %20. You can look at how php encodes URLs and have the Arduino encode the same characters the same way.

do you know if there is an available function that can do this without me needing to write code for it ?

do you know if there is an available function that can do this without me needing to write code for it ?

Not that I know of.

Feeling lazy today, are we? :grin:

unsigned char specials[] = " "; /* String containing chars you want encoded */

static unsigned char hex_digit(unsigned char c)
{  return "01234567890ABCDEF"[c & 0x0F];
}

unsigned char *urlencode(unsigned char *dst,unsigned char *src)
{  unsigned char c,*d = dst;
   while (c = *src++)
   {  if (strchr(specials,c))
      {  *d++ = '%';
         *d++ = hex_digit(c >> 4);
         *d++ = hex_digit(c);
      }
      else *d++ = c;
   }
   return dst;
}

Edit: added declaration of c

OK. So if I get this right, I add the code sample you kindly supplied below my existing function, and change the specials value to :

unsigned char specials[] = "§_DISCOURSE_HOISTED_CODE_0_§+,/:;=?@ <>#%{}|\^~[]`"; /* String containing chars you want encoded */

static unsigned char hex_digit(unsigned char c)
{  return "01234567890ABCDEF"[c & 0x0F];
}

unsigned char *urlencode(unsigned char *dst,unsigned char *src)

and in my function I add :

void LogItWebC(char* LogTxt){

  char URLed = urlencode(LogTxt);

then I get an error on compile :

Invalid conversion from 'char*' to 'unsigned char*'

I have only a basic understanding of why this is happening, but not of how to solve it.

Also, the urlencode function appears to require 2 variables passed to it ( dst and src ). What are they ? I only have 1 char ( LogTxt ) that I want encoded.

Invalid conversion from 'char*' to 'unsigned char*'

I have only a basic understanding of why this is happening, but not of how to solve it.

Change all the unsigned chars to signed chars. That is, simply removed the unsigned keyword.

I only have 1 char ( LogTxt ) that I want encoded.

The encoded string will be longer than the original string, so you need to define and supply a place to store the encoded string.

char specials[] = "§_DISCOURSE_HOISTED_CODE_0_§+,/:;=?@ <>#%{}|~[]`"; ///* String containing chars you want encoded */

static char hex_digit(char c)
{  return "01234567890ABCDEF"[c & 0x0F];
}

char* urlencode(char* dst,char* src)
{  char *d = dst;
   while (c = *src++)
   {  if (strchr(specials,c))
      {  *d++ = '%';
         *d++ = hex_digit(c >> 4);
         *d++ = hex_digit(c);
      }
      else *d++ = c;
   }
   return dst;
}

'c' was not declared in this scope

char* urlencode(char* dst,char* src)
{ char *d = dst;
char c;

Many Thanks

Now the (hopefully) last issue is : what should be passed to :

char* urlencode(char* dst,char* src)

as it looks like it is expecting 2 variables to be passed to it.

void LogItWebC(char* LogTxt)
{
  char encodedTxt[120];
  urlencode(encodedTxt, LogTxt);
.
.
.
  //     client.print(LogTxt);
  client.print(encodedTxt);
.
.
.
}

PaulS first: Yuppers, I should have caught that before posting and you spotted it before I could correct. Thank you.

Dave next: You'll want a buffer to convert into and output from. For sake of discussion, let's call it 'buffer' and make it 80 chars wide:

char buffer[80];

will probably do the job. Now all that's needed is to recode to

client.print(urlencode(buffer,LogTxt));

to output that line in a urlencoded form.

Many Thanks all. ALMOST there.

now the line :

client.print(urlencode(buffer,LogTxt));

gives the error : invalid conversion from 'char*' to 'unsigned char*'

Should I just remove all the 'unsigned' keywords ?

That's what Paul suggested - it'll work. You'll also need to add

#include <string.h>

to your headers to get a prototype for strchr().

couldn't add :
#include <string.h>
as it doesn't exist in my libraries.

I ran the code without it and working well, except for a few odd characters appearing :

2012-04-02---20:01:32 Setup Completed - System OperationalÝ
2012-04-02---20:01:34 Doors OpenN!

and the = converting to < in this line :
2012-04-02---20:01:33 EEProm < 0 (sms OFF+ Home)0state

I added the following to the variable :

char specials[] = "§_DISCOURSE_HOISTED_CODE_0_§+,/:;=?@ <>#%{}|~[]`";

My bad (trying to carry on too many conversations at once) - I forgot to terminate the output string.

Let's try:

char specials[] = "§_DISCOURSE_HOISTED_CODE_0_§+,/:;=?@ <>#%{}|~[]`";

static char hex_digit(c)
{  return "01234567890ABCDEF"[c & 0x0F];
}
char *urlencode(char *dst,char *src)
{  char c,*d = dst;
   while (c = *src++)
   {  if (strchr(specials,c))
      {  *d++ = '%';
         *d++ = hex_digit(c >> 4);
         c = hex_digit(c);
      }
      *d++ = c;
   }
   *d = '\0';
   return dst;
}

It's strange to me that there's no string.h header file, but it'd appear not to have been needed. My ignorance knows no bounds! :grin:

Edit: Removed #include and simplified

Thanks Morris

Working like a dream now !!

Thank You so very much.

Lastly, I just have a question about this function, so that I can hopefully understand it properly :

static char hex_digit(char c)
{  return "01234567890ABCDEF"[c & 0x0F];
}

Is the purpose of this function to return either the character found in the string 01234567890ABCDEF, or if not found, then return the Hex of the 'char c' ?

If so, shouldn't the line 01234567890ABCDEF contain all 26 alpha letters, both upper and lower case ?

It converts the binary value of the low-order four bits of its argument to a hexadecimal digit character. By convention, the digits after 9 are A, B, C, D, E. and F. The number after F, as you might guess, is 10 - decimal 16.

Nice little thread! :slight_smile:

I'm currently having a similar problem -- but the other way around: I'm reading in strings from a POST HTTP response and have to decode the form variable's values. Unfortunately, a string value of "0,255,128" get's sent to the web server (running on the Arduino) as "0%2C255%2C128" because the comma character from the form's 'value=0,255,128' gets urlencoded to %2C.

Sooo, I have to decode HTML entities and was looking for a built-in (in some Arduino lib) function. To no avail.
The search function beamed me to this thread here.

Anybody who has a urldecode() function at hand that'll work on the Arduino?

Thanks so much!
Stefan.

Never mind!

Found something here: Google Code Archive - Long-term storage for Google Code Project Hosting.

Copy & pasted the two functions h2int() and urldecode() into my sketch and they work! :slight_smile: