SIM800L sending image file from memory to HTTP or FTP Server

Hi, I am trying to find ways to send a small (5K) image file from my ESP32 project to my web server .
I have been trying FTP but have experienced several problems.
The latest files are created empty at the server.

But I could try to use HTTP but it requires headings to be sent to the HTTP server and a PHP script at the server to process and store the image file at the server side.

Where can I find the necessary information to be able to build something to help me send the image via http and see if I can have a better result than FTP?

Thanks in advance
Paulo

I had shown a demo script for HTTP form multipart file upload in POST requests. You can refer it from my blog or youtube channel. Its HTTP POST tutorial

Ravi, I have tried http and eventually gave up for FTP.
I can sucessfully transfer an image from SD to FTP server with the code below.
But I have a problem.
almost 50% of the time the image is damaged.
The image is fragmented based on the size of the buffer=1360 so often the last segment is less than the 1360. and on the images that fail the last fragment is the one that is missing.
The AT command that should close the FTP transmission is: AT+FTPPUT=2,0 that signals zero bytes to transfer but it somehow fails to force the FTP server to take the last segment and close the transmission.
Please take a look and see if you can see what might be missing on the code.
Thanks in advance.
Paulo

#include <SPI.h>
#include <SD.h>

char* file_name1 = "text1.txt";
char char_buffer;
String string_buffer = "";
int buffer_space = 1000;
File File1;

void setup() {
  Serial.begin(19200);
  Serial3.begin(19200);
  pinMode(53, OUTPUT);

  if (!SD.begin(53)) {
    Serial.println("Initialization failed!");
    return;
    while(true);
  }else {
    Serial.println("Initialization done.");
  }

  File1 = SD.open(file_name1);
  if (File1) {
    Serial.println("Opening the file: " + String(file_name1) + " done.");
  }else {
    Serial.println("Error opening " + String(file_name1));
    while(true);
  }
   
  Serial.println("Starting...");
  pinMode(7,OUTPUT); //Reset pin of a sim800L
  digitalWrite(7, HIGH);
 
  Serial.println("Starting...");
  gprs_modem_function ();
  Serial.println("The end...");
}


void loop() {
  // put your main code here, to run repeatedly:
}

byte gprs_modem_function (){
  byte reply = 1;
  int i = 0;
  while (i < 10 && reply == 1){ //Try 10 times...
    reply = sendATcommand("AT+CREG?","+CREG: 0,1","ERROR", 1000);
    i++;
    delay(1000);
  }
  if (reply == 0){
    reply = sendATcommand("AT+SAPBR=3,1,\"Contype\",\"GPRS\"","OK","ERROR", 1000);
    if (reply == 0){
      reply = sendATcommand("AT+SAPBR=3,1,\"APN\",\"imovil.entelpcs.cl\"", "OK", "ERROR", 1000);
      if (reply == 0){
        //reply = sendATcommand("AT+SAPBR=3,1,\"USER\",\"entelpcs\"", "OK", "ERROR", 1000);
        if (reply == 0){
          //reply = sendATcommand("AT+SAPBR=3,1,\"PWD\",\"entelpcs\"", "OK", "ERROR", 1000);
          if (reply == 0){
            reply = 2;
            i = 0;
            while (i < 3 && reply == 2){ //Try 3 times...
              reply = sendATcommand("AT+SAPBR=1,1", "OK", "ERROR", 10000);
              if (reply == 2){
                sendATcommand("AT+SAPBR=0,1", "OK", "ERROR", 10000);
              }
              i++;
            }
            if (reply == 0){
              reply = sendATcommand("AT+SAPBR=2,1", "OK", "ERROR", 1000);
              if (reply == 0){
                reply = sendATcommand("AT+FTPCID=1", "OK", "ERROR", 1000);
                if (reply == 0){
                  reply = sendATcommand("AT+FTPSERV=\"ftp.xxx.com\"", "OK", "ERROR", 1000);
                  if (reply == 0){
                    reply = sendATcommand("AT+FTPPORT=21", "OK", "ERROR", 1000);
                    if (reply == 0){
                      reply = sendATcommand("AT+FTPUN=\"monkey\"", "OK", "ERROR", 1000);
                      if (reply == 0){
                        reply = sendATcommand("AT+FTPPW=\"banana\"", "OK", "ERROR", 1000);
                        if (reply == 0){
                          reply = sendATcommand("AT+FTPPUTNAME=\"" + String(file_name1) + "\"", "OK", "ERROR", 1000);
                          if (reply == 0){
                            reply = sendATcommand("AT+FTPPUTPATH=\"/\"", "OK", "ERROR", 1000);
                            if (reply == 0){
                              unsigned int ptime = millis();
                              reply = sendATcommand("AT+FTPPUT=1", "+FTPPUT: 1,1", "+FTPPUT: 1,6", 60000);
                              Serial.println("Time: " + String(millis() - ptime));
                              if (reply == 0){
                                if (File1) {
                                  int i = 0;
                                  while (File1.available()>0) {
                                    char_buffer = File1.read();
                                    string_buffer.concat(char_buffer);
                                    i++;
                                    if (i == buffer_space) {
                                      sendATcommand("AT+FTPPUT=2," + String(buffer_space), "AT+FTPPUT=2,10", "ERROR", 1000);
                                      sendATcommand(string_buffer, "OK", "ERROR", 5000);
                                      string_buffer = "";
                                      i = 0;
                                    }
                                  }
                                  if (string_buffer != ""){
                                    sendATcommand("AT+FTPPUT=2," + String(i), "AT+FTPPUT=2,10", "ERROR", 1000);
                                    sendATcommand(string_buffer, "OK", "ERROR", 5000);
                                    sendATcommand("AT+FTPPUT=2,0", "OK", "ERROR", 1000);  
                                  }
                                  File1.close();
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  return reply;
}

byte sendATcommand(String ATcommand, String answer1, String answer2, unsigned int timeout){
  byte reply = 1;
  String content = "";
  char character;
 
  //Clean the modem input buffer
  while(Serial3.available()>0) Serial3.read();

  //Send the atcommand to the modem
  Serial3.println(ATcommand);
  delay(100);
  unsigned int timeprevious = millis();
  while((reply == 1) && ((millis() - timeprevious) < timeout)){
    while(Serial3.available()>0) {
      character = Serial3.read();
      content.concat(character);
      Serial.print(character);
      delay(10);
    }
    //Stop reading conditions
    if (content.indexOf(answer1) != -1){
      reply = 0;
    }else if(content.indexOf(answer2) != -1){
      reply = 2;
    }else{
      //Nothing to do...
    }
  }
  return reply;
}

The code in my project is not precisely this one but it derives from it.