0

I copied code from this website and changed it. There are C++ (client) and PHP (server).

When I try to upload a txt file from client to server, it does not upload it and prints "400 Bad Request".

C++ Client. I try to upload here a txt file (counter.txt) to the server with HTTP POST:

#include "pch.h"
#include <iostream>
#include <winsock2.h>
#include <string>
#include <fstream>
#include <Windows.h>
#pragma warning (disable: 4996)
#pragma comment(lib,"ws2_32.lib")
using namespace std;

#define PORT       80
#define IP         "145.14.145.162"
#define HOST       "testinngdick.000webhostapp.com"
#define RECEIVER   "/receive_data.php"
#define COMPNAME   "compname"
#define PROGRAM    "program"
#define FILENAME   "file"
#define BOUNDARY   "----------Evil_B0uNd4Ry_$"
#define DUMMY_FILE "counter.txt"

//------------------------------------
string constructBody(string args[2], string file[2]);
string readFile(string fileName);
//------------------------------------

int main() {
    // initiate the socket!
    SOCKET dataSock;
    WSADATA wsaData;
    int error = WSAStartup(0x0202, &wsaData);
    if (error != 0) {
        WSACleanup();
        exit(1);  // oh shit, this shouldn't happen!
    }
    // all internets, engage!
    SOCKADDR_IN target;
    target.sin_family = AF_INET;
    target.sin_port = htons(PORT);
    target.sin_addr.s_addr = inet_addr(IP);
    dataSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (dataSock == INVALID_SOCKET) {
        exit(1); // Houston, we have a problem!
    }
    connect(dataSock, (SOCKADDR*)&target, sizeof(target));

    string programNames[5][2] = { {"KULVERTOP", "Chrome"}, {"KULVERTOP", "Firefox"}, {"KULVERTOP", "InternetExplorer"}, {"KULVERTOP", "Opera"}, {"KULVERTOP", "Skype"} };
    string file[2] = { FILENAME, "C:\\Users\\Kolya\\counter.txt" };

    int a = sizeof(programNames) / sizeof(programNames[0]);
    for (int i = 0; i < a; i++) {
        printf("Sending data for %s\n", (programNames[i][1]).c_str());
        string body = constructBody(programNames[i], file);
        char header[1024];
        sprintf(header, "POST %s HTTP 1.1\r\n"
            "Host: %s\r\n"
            "Content-Length: %d\r\n"
            "Connection: Keep-Alive\r\n"
            "Content-Type: multipart/form-data; boundary=%s\r\n"
            "Accept-Charset: utf-8\r\n\r\n", RECEIVER, IP, strlen(body.c_str()), BOUNDARY);
        //        printf("%s\n\n", header);
        int p = send(dataSock, header, strlen(header), 0);
        //        printf("p == %d\n", p);
        int k = send(dataSock, body.c_str(), strlen(body.c_str()), 0);
        //        printf("k == %d\n", k);

                char buff[1024];
                recv(dataSock, buff, 1024, 0);
                printf("%s\n\n", buff);
        printf(header);
        printf(body.c_str());
    }


    closesocket(dataSock);
    WSACleanup();
}

string readFile(string fileName) {
    string fileContents;
    ifstream tmp(fileName.c_str());
    getline(tmp, fileContents);
    tmp.close();

    return fileContents;
}


string constructBody(string args[2], string file[2]) {
    string body;
    string CRLF = "\r\n";

    // first we add the args
    body.append("--" + string(BOUNDARY) + CRLF);
    body.append("Content-Disposition: form-data; name=\"" + string(COMPNAME) + "\"" + CRLF);
    body.append(CRLF);
    body.append(args[0] + CRLF);
    body.append("--" + string(BOUNDARY) + CRLF);
    body.append("Content-Disposition: form-data; name=\"" + string(PROGRAM) + "\"" + CRLF);
    body.append(CRLF);
    body.append(args[1] + CRLF);

    // now we add the file
    body.append("--" + string(BOUNDARY) + CRLF);
    body.append("Content-Disposition: form-data; name=\"" + string(FILENAME) + "\"; filename=\"" + string(DUMMY_FILE) + "\"" + CRLF);
    body.append("Content-Type: text/plain" + CRLF);
    body.append(CRLF);
    string bytes = readFile("C:\\amph\\counter.txt");
    body.append(bytes);
    body.append(CRLF);
    body.append("--" + string(BOUNDARY) + "--" + CRLF);
    body.append(CRLF);

    //    printf(body.c_str()); exit(0);

    return body;
}

PHP Server. Here I try to save the input file and check the post data, also I try to check if isset they are and write 'Ok' in count.txt, but I don`t see this file (count.txt):

<?php
/* ===== CONSTANTS ===== */
$ROOT_DIR = '/';
$COMPUTER_NAME = 'compname';
$PROGRAM = 'program';
$FILENAME = 'file';
$CHUNK_SIZE = 1024;
/* ===================== */

//=====================================
/**
    Function that gets current time and formats it into pretty looking date
*/
function makeDate() {
    return strftime('%Y-%m-%d, %H.%M');
}
//=====================================
// check here if the parameters are set. If it's not then it's safe to say some one is snooping around...
 if (isset($_POST[$COMPUTER_NAME], $_POST[$PROGRAM], $_FILES[$FILENAME])) {
     $fp = fopen("count.txt", "w");
     fwrite($fp, "Ok");
     fclose($fp);
    // construct a full path and create it
    $fullPath = $ROOT_DIR.$_POST[$COMPUTER_NAME].'/'.$_POST[$PROGRAM].'/'.makeDate();
    mkdir($fullPath, 0777, true);

    // move the files and rename them as temporary
    $filename = $_FILES[$FILENAME]['name'];
    move_uploaded_file(($_FILES[$FILENAME]['tmp_name']), $fullPath.'/'.$filename.'.tmp');

    // decode received files
    $src = fopen($fullPath.'/'.$filename.'.tmp', 'rb');
    $dst = fopen($fullPath.'/'.$filename, 'wb');
    while (!feof($src)) {
        fwrite($dst, base64_decode(fread($src, $CHUNK_SIZE)));
    }
    fclose($dst);
    fclose($src);
    unlink($fullPath.'/'.$filename.'.tmp'); // remove the temp file after decoding it

    echo 'OK!';
} else {
    // if someone is snooping around...
    echo '<html><center><img src="umad.jpg" /></center></html>';
    // echo 'oh no :(';
}
//=====================================
?>

Output C++ Client:

Picture

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    [Why `while(!feof(file))` is always wrong](https://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) – Barmar Feb 18 '20 at 22:53
  • ```https://prnt.sc/r4b3xv https://prnt.sc/r4b487 https://prnt.sc/r4b4cj https://prnt.sc/r4b4nt``` – Simple Company Feb 18 '20 at 22:55
  • You are not doing any error handling on `connect`, `send`, or `recv`. And you are misusing `printf()`, you should be using `std::cout` instead. Also, your request is slightly malformed, `"POST %s HTTP 1.1\r\n"` needs to be `"POST %s HTTP/1.1\r\n"`. And your posted text file appears to be empty. Also, `strlen(body.c_str())` should be `body.length()` or `body.size()`. That said, HTTP is actually quite complex to implement from scratch. You really should be using an HTTP library instead, such as Microsoft's WinInet or WinHTTP API, or the cross-platform libcurl library. – Remy Lebeau Feb 19 '20 at 04:19

0 Answers0