Subversion Repositories ESP8266_P1_Meter

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 raymond 1
// SPDX-License-Identifier: LGPL-3.0-or-later
2
// Copyright 2016-2026 Hristo Gochkov, Mathieu Carbou, Emil Muratov, Will Miles
3
 
4
//
5
// Demo text, binary and file upload
6
//
7
 
8
#include <Arduino.h>
9
#if defined(ESP32) || defined(LIBRETINY)
10
#include <AsyncTCP.h>
11
#include <WiFi.h>
12
#elif defined(ESP8266)
13
#include <ESP8266WiFi.h>
14
#include <ESPAsyncTCP.h>
15
#elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350)
16
#include <RPAsyncTCP.h>
17
#include <WiFi.h>
18
#endif
19
 
20
#include <ESPAsyncWebServer.h>
21
#include <StreamString.h>
22
#include <LittleFS.h>
23
 
24
static AsyncWebServer server(80);
25
 
26
void setup() {
27
  Serial.begin(115200);
28
 
29
  if (!LittleFS.begin()) {
30
    LittleFS.format();
31
    LittleFS.begin();
32
  }
33
 
34
#if ASYNCWEBSERVER_WIFI_SUPPORTED
35
  WiFi.mode(WIFI_AP);
36
  WiFi.softAP("esp-captive");
37
#endif
38
 
39
  // 1. Generate a Lorem_ipsum.txt file of about 20KB of text
40
  //
41
  // 3. Run: curl -v -F "data=@Lorem_ipsum.txt" http://192.168.4.1/upload/text
42
  //
43
  server.on(
44
    "/upload/text", HTTP_POST,
45
    [](AsyncWebServerRequest *request) {
46
      if (!request->_tempObject) {
47
        return request->send(400, "text/plain", "Nothing uploaded");
48
      }
49
      StreamString *buffer = reinterpret_cast<StreamString *>(request->_tempObject);
50
      Serial.printf("Text uploaded:\n%s\n", buffer->c_str());
51
      delete buffer;
52
      request->_tempObject = nullptr;
53
      request->send(200, "text/plain", "OK");
54
    },
55
    [](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
56
      Serial.printf("Upload[%s]: start=%u, len=%u, final=%d\n", filename.c_str(), index, len, final);
57
 
58
      if (!index) {
59
        // first pass
60
        StreamString *buffer = new StreamString();
61
        size_t size = std::max(4094l, request->header("Content-Length").toInt());
62
        Serial.printf("Allocating string buffer of %u bytes\n", size);
63
        if (!buffer->reserve(size)) {
64
          delete buffer;
65
          request->abort();
66
          return;
67
        }
68
        request->_tempObject = buffer;
69
      }
70
 
71
      if (len) {
72
        reinterpret_cast<StreamString *>(request->_tempObject)->write(data, len);
73
      }
74
    }
75
  );
76
 
77
  // 1. Generate a Lorem_ipsum.txt file of about 20KB of text
78
  //
79
  // 3. Run: curl -v -F "data=@Lorem_ipsum.txt" http://192.168.4.1/upload/file
80
  //
81
  server.on(
82
    "/upload/file", HTTP_POST,
83
    [](AsyncWebServerRequest *request) {
84
      if (request->getResponse()) {
85
        // 400 File not available for writing
86
        return;
87
      }
88
 
89
      if (!LittleFS.exists("/my_file.txt")) {
90
        return request->send(400, "text/plain", "Nothing uploaded");
91
      }
92
 
93
      // sends back the uploaded file
94
      request->send(LittleFS, "/my_file.txt", "text/plain");
95
    },
96
    [](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
97
      Serial.printf("Upload[%s]: start=%u, len=%u, final=%d\n", filename.c_str(), index, len, final);
98
 
99
      if (!index) {
100
        request->_tempFile = LittleFS.open("/my_file.txt", "w");
101
 
102
        if (!request->_tempFile) {
103
          request->send(400, "text/plain", "File not available for writing");
104
          return;
105
        }
106
      }
107
      if (len) {
108
        request->_tempFile.write(data, len);
109
      }
110
      if (final) {
111
        request->_tempFile.close();
112
      }
113
    }
114
  );
115
 
116
  //
117
  // Upload a binary file: curl -v -F "data=@file.mp3" http://192.168.4.1/upload/binary
118
  //
119
  server.on(
120
    "/upload/binary", HTTP_POST,
121
    [](AsyncWebServerRequest *request) {
122
      // response already set ?
123
      if (request->getResponse()) {
124
        // 400 No Content-Length
125
        return;
126
      }
127
 
128
      // nothing uploaded ?
129
      if (!request->_tempObject) {
130
        return request->send(400, "text/plain", "Nothing uploaded");
131
      }
132
 
133
      uint8_t *buffer = reinterpret_cast<uint8_t *>(request->_tempObject);
134
      // process the buffer
135
 
136
      delete buffer;
137
      request->_tempObject = nullptr;
138
 
139
      request->send(200, "text/plain", "OK");
140
    },
141
    [](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
142
      Serial.printf("Upload[%s]: start=%u, len=%u, final=%d\n", filename.c_str(), index, len, final);
143
 
144
      // first pass ?
145
      if (!index) {
146
        // Note: using content type to determine size is not reliable!
147
        size_t size = request->header("Content-Length").toInt();
148
        if (!size) {
149
          request->send(400, "text/plain", "No Content-Length");
150
        } else {
151
          Serial.printf("Allocating buffer of %u bytes\n", size);
152
          uint8_t *buffer = new (std::nothrow) uint8_t[size];
153
          if (!buffer) {
154
            // not enough memory
155
            request->abort();
156
            return;
157
          } else {
158
            request->_tempObject = buffer;
159
          }
160
        }
161
      }
162
 
163
      if (len) {
164
        memcpy(reinterpret_cast<uint8_t *>(request->_tempObject) + index, data, len);
165
      }
166
    }
167
  );
168
 
169
  server.begin();
170
}
171
 
172
// not needed
173
void loop() {
174
  delay(100);
175
}