GPRS GET/POST-запросы

Тема в разделе "Arduino & Shields", создана пользователем ardurino, 2 апр 2015.

  1. ardurino

    ardurino Нерд

    Здравствуйте, госпада.

    Столкнулся со странностью:

    Есть сервер, который прнимает GET-запросы.

    http://m-ark.kps-dev.com/restws/session/token/Authorization:Basic:cmVzdF91c3I6amd0aGZuamg=

    Ваш браузер должен, пройдя по этой ссылке получить некий код авторизации.

    Пробую отправить тот же GET-запрос через SIM900.

    Использую такую "конструкцию" в надежде получить тот же ответ от сервера: numdata=inet.httpGET("www.m-ark.kps-dev.com", 80, "/restws/session/token/Authorization:Basic:cmVzdF91c3I6amd0aGZuamg=", msg, 50);

    Но сервер отвечает ошибками 400 или 403. Связь с сервером есть, но запрос серверу не нравится.

    Что же не нравится Ардуине?

    Спасибо. Код прилагаю.

    Код (Text):
    #include "SIM900.h"
    #include <SoftwareSerial.h>
    #include "inetGSM.h"
    //#include "sms.h"
    //#include "call.h"
    //To change pins for Software Serial, use the two lines in GSM.cpp.
    //GSM Shield for Arduino
    //www.open-electronics.org
    //this code is based on the example of Arduino Labs.
    //Simple sketch to start a connection as client.
    InetGSM inet;
    //CallGSM call;
    //SMSGSM sms;
    char msg[50];
    int numdata;
    char inSerial[50];
    int i=0;
    boolean started=false;
    void setup()
    {digitalWrite(9, HIGH);
      //Serial connection.
      Serial.begin(9600);
      Serial.println("GSM Shield testing.");
      //Start configuration of shield with baudrate.
      //For http uses is raccomanded to use 4800 or slower.
      if (gsm.begin(2400)){
        Serial.println("\nstatus=READY");
        started=true;
      }
      else
      digitalWrite(9, HIGH);
      Serial.println("\nstatus=IDLE");
      if(started){
        //GPRS attach, put in order APN, username and password.
        //If no needed auth let them blank.
        if (inet.attachGPRS("internet.beeline.ru", "", ""))
          Serial.println("status=ATTACHED");
        else
        digitalWrite(9, HIGH);
          Serial.println("status=ERROR");
        delay(1000);
        //Read IP address.
        gsm.SimpleWriteln("AT+CIFSR");
        delay(5000);
        //Read until serial buffer is emapty.
        gsm.WhileSimpleRead();
        //TCP Client GET, send a GET request to the server and
        //save the reply.
        numdata=inet.httpGET("www.m-ark.kps-dev.com", 80, "/restws/session/token/Authorization: base: cmVzdF91c3I6amd0aGZuamg=", msg, 50);
        //Print the results.
        Serial.println("\nNumber of data received:");
        Serial.println(numdata);
        Serial.println("\nData received:");
        Serial.println(msg);
      }
    };
    void loop()
    {
      //Read for new byte on serial hardware,
      //and write them on NewSoftSerial.
      serialhwread();
      //Read for new byte on NewSoftSerial.
      serialswread();
    };
    void serialhwread(){
      i=0;
      if (Serial.available() > 0){
        while (Serial.available() > 0) {
          inSerial[i]=(Serial.read());
          delay(10);
          i++;
        }
        inSerial[i]='\0';
        if(!strcmp(inSerial,"/END")){
          Serial.println("_");
          inSerial[0]=0x1a;
          inSerial[1]='\0';
          gsm.SimpleWriteln(inSerial);
        }
        //Send a saved AT command using serial port.
        if(!strcmp(inSerial,"TEST")){
          Serial.println("SIGNAL QUALITY");
          gsm.SimpleWriteln("AT+CSQ");
        }
        //Read last message saved.
        if(!strcmp(inSerial,"MSG")){
          Serial.println(msg);
        }
        else{
          Serial.println(inSerial);
          gsm.SimpleWriteln(inSerial);
        }
        inSerial[0]='\0';
      }
    }
    void serialswread(){
      gsm.SimpleRead();
    }
     
  2. Kopilov

    Kopilov Гик

    Мне и в браузере вернуло "Доступ запрещён" со статусом 403.
    Вероятно, нужны какие-то куки или иные заголовки, имеющиеся в Вашей сессии. (Проверьте, что покажет в другом браузере или через "приватное окно".) Или открыто для определённого диапазона IP.
     
  3. ardurino

    ardurino Нерд

    Да, Fire Fox 37 отозвался ошибкой 403. А Yandex и Chome - прекрасно отвечают. Надо подумать над сервером.
    А кроме inet.httpGET, другие способы отправить get-запрос существуют?
     
  4. Kopilov

    Kopilov Гик

    Отправку запросов из Arduino я не изучал. При отладке своих Web-сервисов на низком уровне использую программу netcat (nc).
    Из браузеров если стабильно разный результат при пустой сессии -- причина может быть в заголовке UserAgent. Однако у меня и из Chrome не открылось.

    Сервер Вы сами писали? Предварительной авторизации с использованием Cookie точно нет?
    Если из "нового окна в режиме инкогнито" будет ошибка -- нехватает какой-то авторизации. Если нет -- у сервера какие-то нестандартные (на мой взгляд) требования к заголовкам (UserAgent или чему-то ещё).

    В общем, анализируйте успешно отправленный запрос с помощью Wireshark или встроенных средств браузера, сравнивайте с отклонёнными. Если причина только в UserAgent -- то хорошо (хотя использовать его для авторизации -- не лучший выбор). Если замешаны Cookie -- то сложнее: если просто скомпрометировать их на клиенте (в ардуине), они могут устареть на сервере. Могут участвовать и другие заголовки.
     
  5. ardurino

    ardurino Нерд


    История получила продолжение: оказывает Ардуина не умеет слать заголовки (Header) в GET и POST-запросах и нужно на более низком уровне это реализовывать.

    Здесь об этом заметка http://stackoverflow.com/questions/...ing-arduino-and-gsm-shield-and-parse-rest-api

    Жаль у меня не получается даже комплирование пройти, что-то компилятору не нравтся.

    Кто может проверит этот код? Буду признателен, если подскажете, как пройти компилироване.
     
  6. ardurino

    ardurino Нерд

  7. Kopilov

    Kopilov Гик

    SVN -- древняя система контроля версий (а code.google.com -- хостинг исходников, который скоро закроется :) ). На данный момент лучший способ скачать с code.google.com -- экспортировать на GitHub.com, они выставили кнопку на видном месте.

    Я экспортировал в свой аккаунт на Гитхабе (удивительно, но быть владельцем проекта на code.google.com для этого не потебовалось), теперь можете открыть проект там https://github.com/Kopilov/gsm-shield-arduino и нажать кнопку "Download ZIP" справа. Или скачать средствами Git :)

    Git (http://git-scm.com/) -- современная система контроля версий с продвинутыми возможностями. Если будете дальше заниматься программированием всерьёз (особенно в команде) -- рекомендую освоить, пригодится.
    Пара хороших руководств:
    http://githowto.com/ru
    http://www-cs-students.stanford.edu/~blynn/gitmagic/intl/ru/
     
  8. ardurino

    ardurino Нерд

    Спасибо, но какие-то чудеса: мне нужен файл inetGSM.ccp он тут https://code.google.com/p/gsm-shiel...branches/CompatibleVerIDE100/inetGSM.cpp?r=71

    с кодом вида:
    intInetGSM::httpPOST(constchar* server,int port,constchar* path,constchar* parameters,char* result,int resultlength)



    strcpy(_buffer,"POST ");
    strcat(_buffer,path);
    strcat(_buffer," HTTP/1.0\nHost: ");
    strcat(_buffer,server);
    //strcat(_buffer,"\n\rUser-Agent: Mozilla/4.0\n\rContent-Length: ");
    strcat(_buffer,"\nContent-Length: ");
    itoa(strlen(parameters),itoaBuffer,10);
    strcat(_buffer,itoaBuffer);
    strcat(_buffer,"\n\n");
    strcat(_buffer,parameters);
    strcat(_buffer,"\n\n");

    потому, что в примере именно в таком виде: strcat(_buffer," HTTP/1.0\nHost: "); пишется код.
    А в том, что вы и я качаем синтаксис в inetGSM.ccp для другой:
    int InetGSM::httpPOST(const char* server, int port, const char* path, const char* parameters, char* result, int resultlength)

    }
    }
    if(!connected) return 0;
    gsm.SimpleWrite("POST ");
    gsm.SimpleWrite(path);
    gsm.SimpleWrite(" HTTP/1.1\nHost: ");
    gsm.SimpleWrite(server);
    gsm.SimpleWrite("\n");
    gsm.SimpleWrite("User-Agent: Arduino\n");
    gsm.SimpleWrite("Content-Type: application/x-www-form-urlencoded\n");
     
  9. ardurino

    ardurino Нерд

    Нужно strcpy(_buffer,"POST "); а есть gsm.SimpleWrite("POST ");
     
  10. Kopilov

    Kopilov Гик

    Это ветка CompatibleVerIDE100, а в предыдущем посте Вы дали ссылку на GSMSHIELD (сравните URL) -- я её наружу и выставил. Можете выбрать желаемую ветку в веб-интерфейсе GitHub (выпадающий список слева у зелёной кнопки), можете скачать весь репозиторий (установить git, выполнить команду git clone https://github.com/Kopilov/gsm-shield-arduino) и потрошить локально.
     
  11. ardurino

    ardurino Нерд

    Я полнейший чайник, не могу архивом скачать нормальным. Не могли бы его в отдельный архивчик вынести? Или мне на почту скинуть или сюда?
    Спасибо.
     
  12. ardurino

    ardurino Нерд

    Даже CompatibleVerIDE100 вообще не могу найти. В списке нет...
     
  13. ardurino

    ardurino Нерд

    Кажется в SIM900IDE022 что-то похожее нашлось...
     
  14. ardurino

    ardurino Нерд

    Уважаемый, какая-то мистика. Ну нету там CompatibleVerIDE100/ Ну не могу найти. Выручите, пожалуйста.
     
  15. Kopilov

    Kopilov Гик

    Да, действительно. И, что интересно, если нажать ссылку "branches" в code.google.com из вашего первого примера -- выводится один список веток (примерно такой же, какой экспортировался в Гитхаб), а если из второго -- то другой, всего две ветки (CompatibleVerIDE100 и CompatibleVer), хотя проект, вроде, этот же. Может, это какие-нибудь скрытые ветки. Code.google.com я никогда не использовал, его тонкостей не знаю.

    Содержимое ветки SIM900IDE022 прикрепил, на всякий случай вместе с репозиторием (каталог .git внутри).
     

    Вложения:

  16. ardurino

    ardurino Нерд

    Спасибо, надеюсь это должно помочь. А я уж думал у меня глюки...
     
  17. ardurino

    ardurino Нерд

    Библиотека установилась, но даже примеры, к сожалению, не компилируются.
     
  18. Kopilov

    Kopilov Гик

    Примеры и ошибки в студию.
     
  19. ardurino

    ardurino Нерд

    Кажется я начинаю понимать суть. Серверу не нравится обращение к нему, это можно исправить переписав в библиотеке файл inetGSM.cpp параметры GET или POST- запросов. А если мы создаём новый вид запроса, например inet.NewhttpPost( ), тогда не забываем его прописать и в inetGSM.h , по аналогии с уже существующими там httpGET, httpPOST - запросам.
    Запрос должен понравиться серверу. В таком виде нужно с сервером изъясняться, в одной из стандартных библиотек.
    if(!connected) return 0;
    gsm.SimpleWrite("POST ");
    gsm.SimpleWrite(path);
    gsm.SimpleWrite(" HTTP/1.1\nHost: ");
    gsm.SimpleWrite(server);
    gsm.SimpleWrite("\n");
    gsm.SimpleWrite("User-Agent: Arduino\n");
    gsm.SimpleWrite("Content-Type: application/x-www-form-urlencoded\n");


    Вопрос вот какой: есть ли какие-то тестовые серверы, для которых известны формы POST-запроса, где можно как раз потестить это самое обращение к серверу?
    Спасибо
     
  20. ardurino

    ardurino Нерд

    Товарищ Копилов мне крупно помог. Теперь проблемка встала на этапе компилирования. Пишу такую строчку с POST-запросом:
    numdata=inet.httpPOST("www.mysite.com", 80, "/my ", "{"title":"temp38", "temperature": "38", "latitude":"44.39 ","longitude":"33.79", "device_id":"28"}",msg,50);
    Не хочет компилировать из-за параметров в { }.
    Выдаёт ошибку:
    This report would have more information with
    "Show verbose output during compilation"
    enabled in File > Preferences.
    Arduino: 1.0.6 (Windows NT (unknown)), Board: "Arduino Uno"
    GPRS_mar31a.ino: In function 'void setup()':
    GPRS_mar31a:58: error: expected `)' before 'title'

    заменяю параметры "{"title":"temp38", "temperature": "38", "latitude":"44.39 ","longitude":"33.79", "device_id":"28"}"
    на строчку из найденного примера (http://forum.arduino.cc/index.php?topic=223171.0) :
    "testas=asd"
    Получаю:
    numdata=inet.httpPOST("www.mysite.com", 80, "/my ", "testas=asd",msg,50);
    И всё компилируется!
    Так что компилятору не нравится в этих параметрах ?
    "{"title":"temp38", "temperature": "38", "latitude":"44.39 ","longitude":"33.79", "device_id":"28"}"
    Чешу репу...