URL Querystring parsing and decoding


oh, i'm sure tons of people have written these. here's mine. sketch runs through few sample urls , feeds them parser.

code: [select]

const char *tests[] = {
  "", // no parameters
  "param1=test", // simple test
  "param1=test&param2=test2", // 2 parameters
  "param1=test&param2=test+2", // parameter encoded space
  "param1=test&param2=c%3a%5cfoodir%5cbarfile.fil", // percent encoding
  "p1=1&p2=2&p3=3&p4=4&p5=5&p6=6&p7=7&p8=8" // more params our test acommodate
};

void setup() {
  // put setup code here, run once:

  serial.begin(9600);

}

void loop() {
  char buf[100];
  char *params[5][2];

  delay(5000);

  (int = 0; < sizeof(tests) / sizeof(*tests); i++) {
    serial.print("parsing \"");
    serial.print(tests[i]);

    // copy test[i] buffer
    // because parser overwrites string passed.
    strcpy(buf, tests[i]);

    // parse buffer params[][]
    int resultsct = parseurlparams(buf, params, 5, true);

    // print off results;

    serial.print("\" produced ");
    serial.print(resultsct);
    serial.print(" parameters:");
    serial.println();

    (int = 0; < resultsct; i++) {
      serial.print("param ");
      serial.print(i);
      serial.print(" name \"");
      serial.print( params[i][0]);
      serial.print("\", param \"");
      serial.print( params[i][1]);
      serial.print("\".");
      serial.println();
    }
    serial.println();
  }
}

/**
 * querystring: string parsed.
 * warning! function overwrites content of string. pass function copy
 * if need value preserved.
 * results: place put pairs of param name/value.
 * resultsmaxct: maximum number of results, = sizeof(results)/sizeof(*results)
 * decodeurl: if true, url escapes decoded per rfc 2616
 */

int parseurlparams(char *querystring, char *results[][2], int resultsmaxct, boolean decodeurl) {
  int ct = 0;

  while (querystring && *querystring && ct < resultsmaxct) {
    results[ct][0] = strsep(&querystring, "&");
    results[ct][1] = strchrnul(results[ct][0], '=');
    if (*results[ct][1]) *results[ct][1]++ = '\0';

    if (decodeurl) {
      percentdecode(results[ct][0]);
      percentdecode(results[ct][1]);
    }

    ct++;
  }

  return ct;
}

/**
 * perform url percent decoding.
 * decoding done in-place , modify parameter.
 */

void percentdecode(char *src) {
  char *dst = src;

  while (*src) {
    if (*src == '+') {
      src++;
      *dst++ = ' ';
    }
    else if (*src == '%') {
      // handle percent escape

      *dst = '\0';
      src++;

      if (*src >= '0' && *src <= '9') {
        *dst = *src++ - '0';
      }
      else if (*src >= 'a' && *src <= 'f') {
        *dst = 10 + *src++ - 'a';
      }
      else if (*src >= 'a' && *src <= 'f') {
        *dst = 10 + *src++ - 'a';
      }

      // cause %4 decoded ascii @, %4 invalid
      // , can't expected decode anyway

      *dst <<= 4;

      if (*src >= '0' && *src <= '9') {
        *dst |= *src++ - '0';
      }
      else if (*src >= 'a' && *src <= 'f') {
        *dst |= 10 + *src++ - 'a';
      }
      else if (*src >= 'a' && *src <= 'f') {
        *dst |= 10 + *src++ - 'a';
      }

      dst++;
    }
    else {
      *dst++ = *src++;
    }

  }
  *dst = '\0';
}



Arduino Forum > Community > Exhibition / Gallery > URL Querystring parsing and decoding


arduino

Comments