vshymanskyy / TinyGSM

A small Arduino library for GSM modules, that just works
GNU Lesser General Public License v3.0
1.91k stars 708 forks source link

TinyGSM GsmClient disconnects after multipart/form-data is sent #780

Open nravanelli opened 4 months ago

nravanelli commented 4 months ago

[X ] I have read the Troubleshooting section of the ReadMe

What type of issues is this?

[X ] Question or request for help

What are you working with?

Modem: SIM7000G Main processor board: ESP32 TinyGSM version: latest Code:

String fileType = "text/plain";
  String content = "--boundary1\r\n";
  content += "Content-Disposition: form-data; name=\"fileToUpload\"; filename=" + fileNameRemote + "\r\n";  // the fileToUpload is the form parameter
  content += "Content-Type: " + fileType + "\r\n\r\n";
  //after this, post the file data.
  String closingContent = "\r\n--boundary1--\r\n";
  client->println(String("POST ") + appCache.uploadFilePath + " HTTP/1.0");
  client->println(String("Host: ") + appCache.host);
  client->println("Keep-Alive: 300");
  client->println("Connection: keep-alive");
  client->println("Content-Length: " + String(content.length() + dataFile.size() + closingContent.length()));
  client->println("Content-Type: multipart/form-data; boundary=boundary1");
  client->println();
  client->println(content);
  if (dataFile) {  // start sending file content
    const size_t bufferSize = 1024;
    char buffer[bufferSize];
    while (dataFile.available()) {
      size_t bytesRead = dataFile.readBytes(buffer, bufferSize);
      client->write((const uint8_t *)buffer, bytesRead);
      fadeLED(3);
    }
    dataFile.close();
  }
  client->print(closingContent);
  //GSMCLIENT DISCONNECTS HERE AFTER 1 SECOND
  // Check HTTP status
  char status[32] = {0};
  client->readBytesUntil('\r', status, sizeof(status));
  // It should be "HTTP/1.0 200 OK" or "HTTP/1.1 200 OK"
  if (strcmp(status + 9, "200 OK") != 0) {
    Serial.print(F("[FILE UPLOAD] Unexpected response: "));
    Serial.println(status);
    deleteClient();
    return false;
  }
  // Skip HTTP headers
  char endOfHeaders[] = "\r\n\r\n";
  if (!client->find(endOfHeaders)) {
    Serial.println(F("[FILE UPLOAD] Invalid response"));
    deleteClient();
    return false;
  }
    // Allocate the JSON document
  JsonDocument doc;
  // Parse JSON object
  DeserializationError error = deserializeJson(doc, *client);
  if (error) {
    Serial.print("deserializeJson() failed: ");
    Serial.println(error.f_str());
    deleteClient();
    return false;
  }
  deleteClient();
  Serial.print(F("[FILE UPLOAD] Response: "));
  Serial.print(doc["code"].as<int>());
  Serial.print(" ");
  Serial.println(doc["message"].as<String>());
  if(doc["code"].as<signed int>() == 200){
    return true;
  }else{
    return false;
  }
}

Scenario, steps to reproduce

Load this code with an appropriate client connection on gsmClient, send a file, await http body.

Expected result

I expect the http response body to be received.

Actual result

When I use this code above to POST a file to my server, the GsmClient disconnects after sending the file. I do in fact receive the file on the server side, but I do not get the response body. Using the same code with WifiClient works as expected. The exact spot where the disconnect occurs is here: //GSMCLIENT DISCONNECTS HERE AFTER 1 SECOND I have diagnosed it is a 1 second disconnect.