Merge pull request #17159 from barbudor/berry_wc_put_delete_patch

Adding PUT, PATCH and DELETE to Berry webclient
This commit is contained in:
s-hadinger 2022-11-21 20:28:48 +01:00 committed by GitHub
commit 1cdc03f835
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 112 additions and 21 deletions

View File

@ -5,8 +5,8 @@
* *
* Copyright (c) 2015 Markus Sattler. All rights reserved. * Copyright (c) 2015 Markus Sattler. All rights reserved.
* This file is part of the HTTPClient for Arduino. * This file is part of the HTTPClient for Arduino.
* Port to ESP32 by Evandro Luis Copercini (2017), * Port to ESP32 by Evandro Luis Copercini (2017),
* changed fingerprints to CA verification. * changed fingerprints to CA verification.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -78,7 +78,7 @@ public:
_recv(recv), _xmit(xmit) _recv(recv), _xmit(xmit)
{ {
} }
std::unique_ptr<WiFiClient> create() override std::unique_ptr<WiFiClient> create() override
{ {
std::unique_ptr<WiFiClient> p = std::unique_ptr<WiFiClient>(new BearSSL::WiFiClientSecure_light(_recv, _xmit)); std::unique_ptr<WiFiClient> p = std::unique_ptr<WiFiClient>(new BearSSL::WiFiClientSecure_light(_recv, _xmit));
@ -569,6 +569,20 @@ int HTTPClientLight::PUT(String payload) {
return PUT((uint8_t *) payload.c_str(), payload.length()); return PUT((uint8_t *) payload.c_str(), payload.length());
} }
/**
* sends a delete request to the server
* @param payload uint8_t *
* @param size size_t
* @return http code
*/
int HTTPClientLight::DELETE(uint8_t * payload, size_t size) {
return sendRequest("DELETE", payload, size);
}
int HTTPClientLight::DELETE(String payload) {
return DELETE((uint8_t *) payload.c_str(), payload.length());
}
/** /**
* sendRequest * sendRequest
* @param type const char * "GET", "POST", .... * @param type const char * "GET", "POST", ....
@ -601,7 +615,7 @@ int HTTPClientLight::sendRequest(const char * type, uint8_t * payload, size_t si
} }
log_d("request type: '%s' redirCount: %d\n", type, redirectCount); log_d("request type: '%s' redirCount: %d\n", type, redirectCount);
// connect to server // connect to server
if(!connect()) { if(!connect()) {
if (_secure) { if (_secure) {
@ -640,7 +654,7 @@ int HTTPClientLight::sendRequest(const char * type, uint8_t * payload, size_t si
// //
redirect = false; redirect = false;
if ( if (
_followRedirects != HTTPC_DISABLE_FOLLOW_REDIRECTS && _followRedirects != HTTPC_DISABLE_FOLLOW_REDIRECTS &&
redirectCount < _redirectLimit && redirectCount < _redirectLimit &&
_location.length() > 0 _location.length() > 0
) { ) {
@ -653,7 +667,7 @@ int HTTPClientLight::sendRequest(const char * type, uint8_t * payload, size_t si
// (the RFC require user to accept the redirection) // (the RFC require user to accept the redirection)
_followRedirects == HTTPC_FORCE_FOLLOW_REDIRECTS || _followRedirects == HTTPC_FORCE_FOLLOW_REDIRECTS ||
// allow GET and HEAD methods without force // allow GET and HEAD methods without force
!strcmp(type, "GET") || !strcmp(type, "GET") ||
!strcmp(type, "HEAD") !strcmp(type, "HEAD")
) { ) {
redirectCount += 1; redirectCount += 1;
@ -972,7 +986,7 @@ String HTTPClientLight::getString(void)
// try to reserve needed memory (noop if _size == -1) // try to reserve needed memory (noop if _size == -1)
if(sstring.reserve((_size + 1))) { if(sstring.reserve((_size + 1))) {
writeToStream(&sstring); writeToStream(&sstring);
return sstring; return sstring;
} else { } else {
log_d("not enough memory to reserve a string! need: %d", (_size + 1)); log_d("not enough memory to reserve a string! need: %d", (_size + 1));
} }
@ -1142,7 +1156,7 @@ bool HTTPClientLight::connect(void)
log_d("transport level verify failed"); log_d("transport level verify failed");
_client->stop(); _client->stop();
return false; return false;
} }
#endif #endif
if(!_client->connect(_host.c_str(), _port, _connectTimeout)) { if(!_client->connect(_host.c_str(), _port, _connectTimeout)) {
log_d("failed connect to %s:%u", _host.c_str(), _port); log_d("failed connect to %s:%u", _host.c_str(), _port);
@ -1150,7 +1164,7 @@ bool HTTPClientLight::connect(void)
} }
// set Timeout for WiFiClient and for Stream::readBytesUntil() and Stream::readStringUntil() // set Timeout for WiFiClient and for Stream::readBytesUntil() and Stream::readStringUntil()
_client->setTimeout((_tcpTimeout + 500) / 1000); _client->setTimeout((_tcpTimeout + 500) / 1000);
log_d(" connected to %s:%u", _host.c_str(), _port); log_d(" connected to %s:%u", _host.c_str(), _port);
@ -1362,8 +1376,8 @@ int HTTPClientLight::writeToStreamDataBlock(Stream * stream, int size)
if(readBytes > buff_size) { if(readBytes > buff_size) {
readBytes = buff_size; readBytes = buff_size;
} }
// stop if no more reading // stop if no more reading
if (readBytes == 0) if (readBytes == 0)
break; break;
@ -1491,8 +1505,8 @@ bool HTTPClientLight::setURL(const String& url)
_port = (_protocol == "https" ? 443 : 80); _port = (_protocol == "https" ? 443 : 80);
} }
// disconnect but preserve _client. // disconnect but preserve _client.
// Also have to keep the connection otherwise it will free some of the memory used by _client // Also have to keep the connection otherwise it will free some of the memory used by _client
// and will blow up later when trying to do _client->available() or similar // and will blow up later when trying to do _client->available() or similar
_canReuse = true; _canReuse = true;
disconnect(true); disconnect(true);

View File

@ -5,8 +5,8 @@
* *
* Copyright (c) 2015 Markus Sattler. All rights reserved. * Copyright (c) 2015 Markus Sattler. All rights reserved.
* This file is part of the HTTPClient for Arduino. * This file is part of the HTTPClient for Arduino.
* Port to ESP32 by Evandro Luis Copercini (2017), * Port to ESP32 by Evandro Luis Copercini (2017),
* changed fingerprints to CA verification. * changed fingerprints to CA verification.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -154,7 +154,7 @@ public:
~HTTPClientLight(); ~HTTPClientLight();
/* /*
* Since both begin() functions take a reference to client as a parameter, you need to * Since both begin() functions take a reference to client as a parameter, you need to
* ensure the client object lives the entire time of the HTTPClientLight * ensure the client object lives the entire time of the HTTPClientLight
*/ */
// bool begin(WiFiClient &client, String url); // bool begin(WiFiClient &client, String url);
@ -194,6 +194,8 @@ public:
int POST(String payload); int POST(String payload);
int PUT(uint8_t * payload, size_t size); int PUT(uint8_t * payload, size_t size);
int PUT(String payload); int PUT(String payload);
int DELETE(uint8_t * payload, size_t size);
int DELETE(String payload);
int sendRequest(const char * type, String payload); int sendRequest(const char * type, String payload);
int sendRequest(const char * type, uint8_t * payload = NULL, size_t size = 0); int sendRequest(const char * type, uint8_t * payload = NULL, size_t size = 0);
int sendRequest(const char * type, Stream * stream, size_t size = 0); int sendRequest(const char * type, Stream * stream, size_t size = 0);

View File

@ -1,8 +1,8 @@
/******************************************************************** /********************************************************************
* Webclient mapped to Arduino framework * Webclient mapped to Arduino framework
* *
* To use: `d = webclient()` * To use: `d = webclient()`
* *
*******************************************************************/ *******************************************************************/
#include "be_constobj.h" #include "be_constobj.h"
@ -20,6 +20,9 @@ extern int wc_close(bvm *vm);
extern int wc_addheader(bvm *vm); extern int wc_addheader(bvm *vm);
extern int wc_GET(bvm *vm); extern int wc_GET(bvm *vm);
extern int wc_POST(bvm *vm); extern int wc_POST(bvm *vm);
extern int wc_PUT(bvm *vm);
extern int wc_PATCH(bvm *vm);
extern int wc_DELETE(bvm *vm);
extern int wc_getstring(bvm *vm); extern int wc_getstring(bvm *vm);
extern int wc_writefile(bvm *vm); extern int wc_writefile(bvm *vm);
extern int wc_writeflash(bvm *vm); extern int wc_writeflash(bvm *vm);
@ -49,6 +52,9 @@ class be_class_webclient (scope: global, name: webclient) {
add_header, func(wc_addheader) add_header, func(wc_addheader)
GET, func(wc_GET) GET, func(wc_GET)
POST, func(wc_POST) POST, func(wc_POST)
PUT, func(wc_PUT)
PATCH, func(wc_PATCH)
DELETE, func(wc_DELETE)
get_string, func(wc_getstring) get_string, func(wc_getstring)
write_file, func(wc_writefile) write_file, func(wc_writefile)
write_flash, func(wc_writeflash) write_flash, func(wc_writeflash)

View File

@ -76,9 +76,9 @@ String wc_UrlEncode(const String& text) {
/*********************************************************************************************\ /*********************************************************************************************\
* Native functions mapped to Berry functions * Native functions mapped to Berry functions
* *
* import webclient * import webclient
* *
\*********************************************************************************************/ \*********************************************************************************************/
extern "C" { extern "C" {
// Berry: `` // Berry: ``
@ -428,6 +428,75 @@ extern "C" {
be_raise(vm, kTypeError, nullptr); be_raise(vm, kTypeError, nullptr);
} }
// wc.PUT(string | bytes) -> httpCode:int
int32_t wc_PUT(struct bvm *vm);
int32_t wc_PUT(struct bvm *vm) {
int32_t argc = be_top(vm);
if (argc >= 2 && (be_isstring(vm, 2) || be_isbytes(vm, 2))) {
HTTPClientLight * cl = wc_getclient(vm);
const char * buf = nullptr;
size_t buf_len = 0;
if (be_isstring(vm, 2)) { // string
buf = be_tostring(vm, 2);
buf_len = strlen(buf);
} else { // bytes
buf = (const char*) be_tobytes(vm, 2, &buf_len);
}
uint32_t http_connect_time = millis();
int32_t httpCode = cl->PUT((uint8_t*)buf, buf_len);
wc_errorCodeMessage(httpCode, http_connect_time);
be_pushint(vm, httpCode);
be_return(vm); /* return code */
}
be_raise(vm, kTypeError, nullptr);
}
// wc.PATCH(string | bytes) -> httpCode:int
int32_t wc_PATCH(struct bvm *vm);
int32_t wc_PATCH(struct bvm *vm) {
int32_t argc = be_top(vm);
if (argc >= 2 && (be_isstring(vm, 2) || be_isbytes(vm, 2))) {
HTTPClientLight * cl = wc_getclient(vm);
const char * buf = nullptr;
size_t buf_len = 0;
if (be_isstring(vm, 2)) { // string
buf = be_tostring(vm, 2);
buf_len = strlen(buf);
} else { // bytes
buf = (const char*) be_tobytes(vm, 2, &buf_len);
}
uint32_t http_connect_time = millis();
int32_t httpCode = cl->PATCH((uint8_t*)buf, buf_len);
wc_errorCodeMessage(httpCode, http_connect_time);
be_pushint(vm, httpCode);
be_return(vm); /* return code */
}
be_raise(vm, kTypeError, nullptr);
}
// wc.DELETE(string | bytes) -> httpCode:int
int32_t wc_DELETE(struct bvm *vm);
int32_t wc_DELETE(struct bvm *vm) {
int32_t argc = be_top(vm);
if (argc >= 2 && (be_isstring(vm, 2) || be_isbytes(vm, 2))) {
HTTPClientLight * cl = wc_getclient(vm);
const char * buf = nullptr;
size_t buf_len = 0;
if (be_isstring(vm, 2)) { // string
buf = be_tostring(vm, 2);
buf_len = strlen(buf);
} else { // bytes
buf = (const char*) be_tobytes(vm, 2, &buf_len);
}
uint32_t http_connect_time = millis();
int32_t httpCode = cl->DELETE((uint8_t*)buf, buf_len);
wc_errorCodeMessage(httpCode, http_connect_time);
be_pushint(vm, httpCode);
be_return(vm); /* return code */
}
be_raise(vm, kTypeError, nullptr);
}
int32_t wc_getstring(struct bvm *vm); int32_t wc_getstring(struct bvm *vm);
int32_t wc_getstring(struct bvm *vm) { int32_t wc_getstring(struct bvm *vm) {
HTTPClientLight * cl = wc_getclient(vm); HTTPClientLight * cl = wc_getclient(vm);
@ -547,7 +616,7 @@ extern "C" {
be_raisef(vm, "internal_error", "failed, written %i bytes vs %i", written, size); be_raisef(vm, "internal_error", "failed, written %i bytes vs %i", written, size);
} }
AddLog(LOG_LEVEL_DEBUG, D_LOG_UPLOAD "flash writing succesful"); AddLog(LOG_LEVEL_DEBUG, D_LOG_UPLOAD "flash writing succesful");
be_pushint(vm, written); be_pushint(vm, written);
be_return(vm); /* return code */ be_return(vm); /* return code */
} }