Парсинг POST запроса со строковыми значениями

vac
Offline
Зарегистрирован: 01.04.2017

Доброго времени суток форумчане.

Ищу пример парсинга пост запроса типа:

/set_settings?ipaddr=192.168.0.10&mask=255.255.255.0&gate=192.168.0.1&server=192.168.0.100&port=1000&udp=1

Тут и строки и числа...

Если у кого имеется заделитесь пожалуйста!

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Это не POST-запрос, а GET-запрос. Вам нужно распарсить query string? После ? - идут пары ключ=значение, разделитель - &. Парсится в соответствии с этими вводными. Не забывайте про то, что там могут быть escape-последовательности, например, %20 - это пробел. Подробнее - есть в RFC по HTTP.

rkit
Онлайн
Зарегистрирован: 23.11.2016

Это совсем не запрос, а https://ru.wikipedia.org/wiki/URL.

rkit
Онлайн
Зарегистрирован: 23.11.2016

Запрос выглядит вот так

POST http://arduino.ru/comment/edit/523445 HTTP/1.1
Host: arduino.ru
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 380
Origin: http://arduino.ru
DNT: 1
Connection: keep-alive
Referer: http://arduino.ru/forum/programmirovanie/parsing-post-zaprosa-so-strokovymi-znacheniyami
Cookie: 
Upgrade-Insecure-Requests: 1

comment=%3Cp%3E%D0%AD%D1%82%D0%BE+%D1%81%D0%BE%D0%B2%D1%81%D0%B5%D0%BC+%D0%BD%D0%B5+%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%2C+%D0%B0+https%3A%2F%2Fru.wikipedia.org%2Fwiki%2FURL.%3C%2Fp%3E%0D%0A&form_build_id=form-16ca38eada3ad8b0a8fc50d12f5b3a67&form_token=44768f869f9827e7315fbaf9e9e1faeb&form_id=comment_form&notify_type=1&op=%D0%A1%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B8%D1%82%D1%8C

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Есть библиотека специально для парсинга всего, чего угодно.

vac
Offline
Зарегистрирован: 01.04.2017

vac пишет:

Доброго времени суток форумчане.

Ищу пример парсинга пост запроса типа:

/set_settings?ipaddr=192.168.0.10&mask=255.255.255.0&gate=192.168.0.1&server=192.168.0.100&port=1000&udp=1

Тут и строки и числа...

Если у кого имеется заделитесь пожалуйста!

Многоуважаемые! Я говорю про конкретную строку, которую нужно парсить:

ipaddr=192.168.0.10&mask=255.255.255.0&gate=192.168.0.1&server=192.168.0.100&port=1000&udp=1

Есть ли рабочие примеры? За что буду сильно благодарен... И да... Выражения, могут же меняться местами, могут и отсутствовать.. Это как пример... За ранее спасибо!

vac
Offline
Зарегистрирован: 01.04.2017

DIYMan пишет:

Вам нужно распарсить query string? После ? - идут пары ключ=значение, разделитель - &. Парсится в соответствии с этими вводными. Не забывайте про то, что там могут быть escape-последовательности, например, %20 - это пробел. Подробнее - есть в RFC по HTTP.

Точно!

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

vac пишет:

Многоуважаемые! Я говорю про конкретную строку, которую нужно парсить:

ipaddr=192.168.0.10&mask=255.255.255.0&gate=192.168.0.1&server=192.168.0.100&port=1000&udp=1

Вам нужен пример для этой конкретной строки? Боюсь, что таких нет.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ЕвгенийП пишет:

vac пишет:

Многоуважаемые! Я говорю про конкретную строку, которую нужно парсить:

ipaddr=192.168.0.10&mask=255.255.255.0&gate=192.168.0.1&server=192.168.0.100&port=1000&udp=1

Вам нужен пример для этой конкретной строки? Боюсь, что таких нет.

Эта проблема элементарно решается в разделе "Ищу исполнителя".

b707
Offline
Зарегистрирован: 26.05.2017

vac пишет:

Многоуважаемые! Я говорю про конкретную строку, которую нужно парсить:

ipaddr=192.168.0.10&mask=255.255.255.0&gate=192.168.0.1&server=192.168.0.100&port=1000&udp=1

Есть ли рабочие примеры?

https://forum.arduino.cc/index.php?topic=44646.0

vac
Offline
Зарегистрирован: 01.04.2017

b707 пишет:

vac пишет:

Многоуважаемые! Я говорю про конкретную строку, которую нужно парсить:

ipaddr=192.168.0.10&mask=255.255.255.0&gate=192.168.0.1&server=192.168.0.100&port=1000&udp=1

Есть ли рабочие примеры?

https://forum.arduino.cc/index.php?topic=44646.0

Спасибо за ссылку, но не компилистся тот пример... 

WScript.h библиотека похоже не работает.

query_string:43:12: error: 'class String' has no member named 'append'; did you mean 'end'?

 readString.append(c);

            ^~~~~~

            end

query_string:53:16: error: 'class String' has no member named 'contains'; did you mean 'concat'?

  if(readString.contains("-")) { //test for servo control sring

                ^~~~~~~~

                concat

query_string:69:16: error: 'class String' has no member named 'contains'; did you mean 'concat'?

  if(readString.contains("Slidervalue")) {

                ^~~~~~~~

                concat

exit status 1
'class String' has no member named 'append'; did you mean 'end'?

 

 

negavoid
Offline
Зарегистрирован: 09.07.2016

Чо сразу Wstring.h-то, она устала, она retired...

readString += c;
...
if (readString.indexOf("-") != -1) { ... }

 

vac
Offline
Зарегистрирован: 01.04.2017
void parseQueryString(String buffer)  {
  Serial.println(buffer);
    int maxIndex = buffer.length() - 1;
    int index=0;
    int next_index = 0;
    int cmdcount = 0;
    String cmd1[10];
   
    do {
        next_index = buffer.indexOf('&', index);
        cmd1[cmdcount] = buffer.substring(index, next_index);
        index = next_index + 1;
        cmdcount = cmdcount + 1;
     } while ((next_index != -1) && (next_index < maxIndex) && cmdcount < 10);

Serial.print("cmdcount=");Serial.println(cmdcount);

for (int i=0; i < cmdcount; i++) {
index = cmd1[i].indexOf('=');
executeCMD(cmd1[i].substring(0,index), cmd1[i].substring(index+1,cmd1[i].length()));
}
}

void executeCMD(String cmd, String data) {
Serial.print("CMD: ");Serial.print(cmd);
Serial.print(" data: ");Serial.println(data);
  
}

Если кому понадобится, решение получилось такое.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

vac пишет:

Если кому понадобится, решение получилось такое.

А что будет, если ему подсунуть строку из стартового поста?

/set_settings?ipaddr=192.168.0.10&mask=255.255.255.0&gate=192.168.0.1&server=192.168.0.100&port=1000&udp=1

Неужели правильно отработает?

negavoid
Offline
Зарегистрирован: 09.07.2016

Я б лучше подсунул cmd 50кб длиной и 50кб data :) Воистину, мир IoT - мир DoS :)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

negavoid пишет:

Я б лучше подсунул cmd 50кб длиной и 50кб data :)

Ну, я не садист, я скромненько предлагаю строчку, которая собственно и была затравочной в теме, без каких-либо изменений :-)

negavoid
Offline
Зарегистрирован: 09.07.2016

Лучше сразу с плеча, зато потом ботнетов типа Mirai меньше будет :) Хотя нет, всё равно ведь будут, ну не здесь, так в другом месте напарсят строк с шеллкодом :)

vac
Offline
Зарегистрирован: 01.04.2017

ЕвгенийП пишет:

vac пишет:

Если кому понадобится, решение получилось такое.

А что будет, если ему подсунуть строку из стартового поста?

/set_settings?ipaddr=192.168.0.10&mask=255.255.255.0&gate=192.168.0.1&server=192.168.0.100&port=1000&udp=1

Неужели правильно отработает?

Пост №5 и 6, я поправился

vac
Offline
Зарегистрирован: 01.04.2017

negavoid пишет:

Я б лучше подсунул cmd 50кб длиной и 50кб data :) Воистину, мир IoT - мир DoS :)

Ну это ж кусок кода...

EthernetClient client = server.available();
  if (client) { 
    String readString = "";
    String buffer = ""; 
    boolean nf1 = true;
    boolean nf2 = false;
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
  if(readString.length() <= readMax) readString +=c;  // Для экономии памяти записывает не весь заголовок, а то что нужно
        if (c == '\n' && currentLineIsBlank) {
          
          while(client.available()) {      //Обработка запроса POST
            post = client.read();   
            if(buffer.length() <= bufferMax) buffer +=post; 
          }
readMax bufferMax
DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Чой-то вспомнилось - когда-то давно делал разбор пар ключ-значение для любого наследника Stream: https://github.com/Porokhnya/ArduinoParamsFromStream Там просто, как три копейки, и требует один промежуточный буфер, для каждой пары ключ=значение - вызывается callback. Можно там подсмотреть принцип, если вдруг...

З.Ы. Без претензий.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

vac пишет:

Пост №5 и 6, я поправился

Ну, Бог с Вами. Но уж хотя бы строку-то по ссылке передавайте или уж, на самый худой конец, проверяйте. Прибежите же потом "а чего у меня рандомно глючит". Чего ж Вы все так себя не любите-то?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Начинающие набаловались Srting ом, мозг включать не хотят (
Так что в условиях ограниченных ресурсов МК учиться программировать не хотят (

PS. Извиняюсь, может не в тему, выпил, депресняк, сегодня, молодому коллеге сисадмину пытался объяснить что делает echo в PHP и как это все работает - беда (

sadman41
Offline
Зарегистрирован: 19.10.2016

Объяснил или за второй побежали?

negavoid
Offline
Зарегистрирован: 09.07.2016

Когда смотрю на унутренности зенда, тоже иногда хочу за второй сбегать

vac
Offline
Зарегистрирован: 01.04.2017

Господа! Это же не профф. форум девелоперов софта для промышленных решений! Это ардуино! – платформа для изучения основ – так сказать!

Я до этого писал на VB, для меня действительно, ссылки на переменные и объекты пока сложно варятся. Но не отбивайте желание. Вкус приходит во время еды….

sadman41
Offline
Зарегистрирован: 19.10.2016

negavoid пишет:

Когда смотрю на унутренности зенда, тоже иногда хочу за второй сбегать

Никогда не приходила мысль о необходимости разбора несломанного перфоратора или работающего смартфона? ;)

rkit
Онлайн
Зарегистрирован: 23.11.2016

vac пишет:

Это ардуино! – платформа для изучения основ – так сказать!

Совершенно наоборот. Ардуино делает всё возможное, чтобы пользователь с основами не сталкивался.

negavoid
Offline
Зарегистрирован: 09.07.2016

sadman41 пишет:

Никогда не приходила мысль о необходимости разбора несломанного перфоратора или работающего смартфона? ;)

Приходила. Только тогда это был не смартфон, а sony cmd-j5, j70 и иже с ними. После этой мысли появился, как это сейчас говорят, "разлок бутлоадера", а после него фреймворк, а далее всякие разные люди понаписали игр и приложений для этой серии. Что в условиях секции кода по 16 кб было вовсе непросто. Оверлеи на телефоне - сурово. ar-gcc работал под нестабильным тогда ещё cygwin, что добавляло изюминку.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

vac пишет:

Но не отбивайте желание. 

Да, кто ж Вам отбивает? Я написал "поправьте" - нафига на ровном месте память дублировать? Там правки-то - один (!!!) символ вставить. Как править и почему я тут давно уж всем новичкам объяснил. Если у Вас совет поправить отбивает желание, возникают сомнения, а есть ли оно вообще.

vac
Offline
Зарегистрирован: 01.04.2017

ЕвгенийП пишет:

Да, кто ж Вам отбивает? Я написал "поправьте" - нафига на ровном месте память дублировать? Там правки-то - один (!!!) символ вставить. Как править и почему я тут давно уж всем новичкам объяснил. Если у Вас совет поправить отбивает желание, возникают сомнения, а есть ли оно вообще.

Спасибо за ссылку!