Skip to content
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
To upload through terminal you can use: curl -F "[email protected]" esp8266-webupdate.local/update
*/

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <ESP8266HTTPUpdateServer.h>

const char* host = "esp8266-webupdate";
const char* update_path = "/firmware";
const char* update_username = "admin";
const char* update_password = "admin";
const char* ssid = "........";
const char* password = "........";

ESP8266WebServer httpServer(80);
ESP8266HTTPUpdateServer httpUpdater;

void setup(void){

Serial.begin(115200);
Serial.println();
Serial.println("Booting Sketch...");
WiFi.mode(WIFI_AP_STA);
WiFi.begin(ssid, password);

while(WiFi.waitForConnectResult() != WL_CONNECTED){
WiFi.begin(ssid, password);
Serial.println("WiFi failed, retrying.");
}

MDNS.begin(host);

httpUpdater.setup(&httpServer, update_path, update_username, update_password);
httpServer.begin();

MDNS.addService("http", "tcp", 80);
Serial.printf("HTTPUpdateServer ready! Open http://%s.local%s in your browser and login with username '%s' and password '%s'\n", host, update_path, update_username, update_password);
}

void loop(void){
httpServer.handleClient();
delay(1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delay not needed here

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah... was in the other example, so I left it there thinking might be needed. I'll remove it from both

}
37 changes: 25 additions & 12 deletions libraries/ESP8266HTTPUpdateServer/src/ESP8266HTTPUpdateServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


const char* ESP8266HTTPUpdateServer::_serverIndex =
R"(<html><body><form method='POST' action='/update' enctype='multipart/form-data'>
R"(<html><body><form method='POST' action='' enctype='multipart/form-data'>
<input type='file' name='update'>
<input type='submit' value='Update'>
</form>
Expand All @@ -17,24 +17,29 @@ ESP8266HTTPUpdateServer::ESP8266HTTPUpdateServer(bool serial_debug)
{
_serial_output = serial_debug;
_server = NULL;
_username = NULL;
_password = NULL;
_authenticated = false;
}

void ESP8266HTTPUpdateServer::setup(ESP8266WebServer *server)
void ESP8266HTTPUpdateServer::setup(ESP8266WebServer *server, const char * path, const char * username, const char * password)
{
_server = server;
_username = (char *)username;
_password = (char *)password;

// handler for the /update form page
_server->on("/update", HTTP_GET, [&](){
_server->sendHeader("Connection", "close");
_server->sendHeader("Access-Control-Allow-Origin", "*");
_server->on(path, HTTP_GET, [&](){
if(_username != NULL && _password != NULL && !_server->authenticate(_username, _password))
return _server->requestAuthentication();
_server->send(200, "text/html", _serverIndex);
});

// handler for the /update form POST (once file upload finishes)
_server->on("/update", HTTP_POST, [&](){
_server->sendHeader("Connection", "close");
_server->sendHeader("Access-Control-Allow-Origin", "*");
_server->send(200, "text/html", (Update.hasError())?"FAIL":"<META http-equiv=\"refresh\" content=\"15;URL=/update\">OK");
_server->on(path, HTTP_POST, [&](){
if(!_authenticated)
return _server->requestAuthentication();
_server->send(200, "text/html", (Update.hasError())?"FAIL":"<META http-equiv=\"refresh\" content=\"15;URL=\">OK");
ESP.restart();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@igrr you think maybe we should not reboot if Update failed?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll merge this as is, let's address this in a separate pull request. I think a good idea would be to add update callbacks similar to ESP8266HTTPUpdate (client). Actually maybe we need to review APIs of HTTP update client and HTTP update server and make them more uniform. Let's discuss further on gitter.

},[&](){
// handler for the file upload, get's the sketch bytes, and writes
Expand All @@ -43,27 +48,35 @@ void ESP8266HTTPUpdateServer::setup(ESP8266WebServer *server)
if(upload.status == UPLOAD_FILE_START){
if (_serial_output)
Serial.setDebugOutput(true);

_authenticated = (_username == NULL || _password == NULL || _server->authenticate(_username, _password));
if(!_authenticated){
if (_serial_output)
Serial.printf("Unauthenticated Update\n");
return;
}

WiFiUDP::stopAll();
if (_serial_output)
Serial.printf("Update: %s\n", upload.filename.c_str());
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
if(!Update.begin(maxSketchSpace)){//start with max available size
if (_serial_output) Update.printError(Serial);
}
} else if(upload.status == UPLOAD_FILE_WRITE){
} else if(_authenticated && upload.status == UPLOAD_FILE_WRITE){
if (_serial_output) Serial.printf(".");
if(Update.write(upload.buf, upload.currentSize) != upload.currentSize){
if (_serial_output) Update.printError(Serial);

}
} else if(upload.status == UPLOAD_FILE_END){
} else if(_authenticated && upload.status == UPLOAD_FILE_END){
if(Update.end(true)){ //true to set the size to the current progress
if (_serial_output) Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
} else {
if (_serial_output) Update.printError(Serial);
}
if (_serial_output) Serial.setDebugOutput(false);
} else if(upload.status == UPLOAD_FILE_ABORTED){
} else if(_authenticated && upload.status == UPLOAD_FILE_ABORTED){
Update.end();
if (_serial_output) Serial.println("Update was aborted");
}
Expand Down
21 changes: 20 additions & 1 deletion libraries/ESP8266HTTPUpdateServer/src/ESP8266HTTPUpdateServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,28 @@ class ESP8266HTTPUpdateServer
bool _serial_output;
ESP8266WebServer *_server;
static const char *_serverIndex;
char * _username;
char * _password;
bool _authenticated;
public:
ESP8266HTTPUpdateServer(bool serial_debug=false);
void setup(ESP8266WebServer *server=NULL);

void setup(ESP8266WebServer *server)
{
setup(server, NULL, NULL);
}

void setup(ESP8266WebServer *server, const char * path)
{
setup(server, path, NULL, NULL);
}

void setup(ESP8266WebServer *server, const char * username, const char * password)
{
setup(server, "/update", username, password);
}

void setup(ESP8266WebServer *server, const char * path, const char * username, const char * password);
};


Expand Down