esp8266 Digest авторизация принятый урл со стороннего контроллера
- Войдите на сайт для отправки комментариев
Ср, 08/04/2020 - 21:11
Добрый вечер всем, возникла проблема при разборе Digest авторизации, код взят из примера, сервер указал локальный на котором крутится апач, код взят из примера к модулю:
volatile bool send_data=0; static String email_my = "test"; static String password_my = "test"; const char *myserver = "http://test"; String url = ""; //************************************************************************************* //Авторизация //************************************************************************************* String exractParam(String& authReq, const String& param, const char delimit) { int _begin = authReq.indexOf(param); if (_begin == -1) { return ""; } return authReq.substring(_begin + param.length(), authReq.indexOf(delimit, _begin + param.length())); } String getCNonce(const int len) { static const char alphanum[] = "0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"; String s = ""; for (int i = 0; i < len; ++i) { s += alphanum[rand() % (sizeof(alphanum) - 1)]; } return s; } String getDigestAuth(String& authReq, String username, String password, String url,unsigned int counter) { // extracting required parameters for RFC 2069 simpler Digest String realm = exractParam(authReq, "realm=\"", '"'); String nonce = exractParam(authReq, "nonce=\"", '"'); String cNonce = getCNonce(8); char nc[9]; snprintf(nc, sizeof(nc), "%08x", counter); // parameters for the RFC 2617 newer Digest MD5Builder md5; md5.begin(); md5.add(username + ":" + realm + ":" + password); // md5 of the user:realm:user md5.calculate(); String h1 = md5.toString(); md5.begin(); md5.add(String("GET:") + url); md5.calculate(); String h2 = md5.toString(); md5.begin(); md5.add(h1 + ":" + nonce + ":" + String(nc) + ":" + cNonce + ":" + "auth" + ":" + h2); md5.calculate(); String response = md5.toString(); String authorization = "Digest username=\"" + username + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", uri=\"" + url + "\", algorithm=\"MD5\", qop=auth, nc=" + String(nc) + ", cnonce=\"" + cNonce + "\", response=\"" + response + "\""; Serial.println(authorization); return authorization; } //************************************************************************************* //Авторизоваться и послать данные в порт //************************************************************************************* void SendData() { WiFiClient client; HTTPClient http; Serial.print("[HTTP] begin...\n"); // configure traged server and url http.begin(client, String(myserver) + String(url)); const char *keys[] = {"WWW-Authenticate"}; http.collectHeaders(keys, 1); Serial.print("[HTTP] GET...\n"); // start connection and send HTTP header int httpCode = http.GET(); if (httpCode > 0) { String authReq = http.header("WWW-Authenticate"); //Serial.println(authReq); String authorization = getDigestAuth(authReq, email_my, password_my, String(url), 1); http.end(); http.begin(client, String(myserver) + String(url)); http.addHeader("Authorization", authorization); int httpCode = http.GET(); if (httpCode > 0) { String payload = http.getString(); Serial.println(payload); //Разбор пришедшего JSON //Parsing(payload); MySerial.println(payload); } else { Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); } } else { Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); } http.end(); }
блок setup не пишу чтобы не засорять код, модуль подключается к WIFI и идет метод loop:
void loop(void) { ReadSerial(); if(send_data==1){SendData();send_data=0;} } void ReadSerial() { static String data=""; if(MySerial.available()>0) { char temp=MySerial.read(); if (temp == '\n') { Serial.println(data); url = data; data=""; MySerial.flush(); send_data=1; } else { data+= temp; } } }
строка которая приходит с другого контроллера имеет вид: \?t=10 ее я вижу при выводе Serial.println, но сервер отвечает 400 Bad Request, однако если я присваиваю вместо url = data; url="\?t=10"; Все отлично выполняется и от сервера я получаю ответ, почему так происходит? как решить данную проблему?
в тексте ошибся в последнем, слеш используется / а не как я написал
В функции ReadSerial в data попадает также символ '\r', если перевод строки настроен как \r\n. Возможно, это играет роль.
Так у меня другой контроллер просто отправляет Serial.println("/?t=10"); Это я не вручную пишу (в мониторе порта)
А вы правы, только как это убрать чтобы не отправлять доп знаки, сейчас отправил с контроллера вот так:
Serial.print("/?time=10@");
а в приеме написал вот так:
И все прошло, только хотелось бы не добавлять к урл дополнительные знаки
Так у меня другой контроллер просто отправляет Serial.println("/?t=10"); Это я не вручную пишу (в мониторе порта)
println добавляет в конец печатаемых данных два символа - \r\n.
А вы правы, только как это убрать чтобы не отправлять доп знаки
Вы не сами писали, что ли? У вас есть сравнение с '\n'. Что мешает сделать else if и сравнение с '\r', при этом в блоке ничего не плюсовать к data?
Да так заработало, else if(temp == '\r'){} спасибо большое