-1

I am trying to upload an image to the server but the request will not end. In DevTools, the request shows as pending while, in the backend, php is continuously writing to an ever growing file until I have to restart Apache in order to stop the request.

I am using CodeIgniter on the backend to handle uploads. The exact same code used in other parts of my code works just fine.

This is the request code. The event is attached to a file input field:

$("body").on("change", "#product-image", function(e) {
    if ($.inArray($(this).val().split('.').pop().toLowerCase(), allowedExt) == -1) {
        alert("JPG JPEG PNG only");
        $(this).val(null);
    } else {
        var formData = new FormData();
        var file = $(this)[0].files[0];
        formData.append("Image", file);
        formData.append("ProductID", <?= $ProductID; ?>);
        $.ajax({
            url: "/rest/private/product/image/upload",
            method: "POST",
            data: formData,
            processData: false,
            contentType: false,
            cache: false,
            success: function(response) {
                var resp = JSON.parse(response);
                if (resp.Status == 1) {
                    var url = resp.Data.URL;
                    var order = resp.Data.Order;
                    var ID = resp.Data.ID;
                    self.showPreview("<?= base_url() ?>" + url, order, ID);
                } else {
                    self.errorToast(resp.Error.Image);
                }
            },
            error: function(resp) {
                self.errorToast("Error");
            },
        });
    }
});

This is the code that handles the upload:

$Image = $this->request->getFile("Image");


$maxW = "5000";
$maxH = "5000";
$maxSize = 4;
$validationRule = [
    "Image" => [
        'label' => 'Your Image',
        'rules' => [
            'uploaded[Image]',
            'is_image[Image]',
            'mime_in[Image,image/jpg,image/jpeg,image/gif,image/png,image/webp,image/bmp,image/tiff]',
            'max_size[Image,' . $maxSize * 1024 . ']',
            'max_dims[Image,' . $maxW . "," . $maxH . ']',
        ],
        'errors' => [
            'max_dims' => '{field} is bigger than (' . $maxW . "x" . $maxH . ')',
            'max_size' => '{field} is bigger than ' . $maxSize . 'MB',
        ],
    ],
];

if (!$this->validateData(["Image" => $Image], $validationRule)) {
    $this->resp["Status"] = 0;
    $this->resp["Error"] = $this->validator->getErrors();
    return;
}

if ($Image->isValid() && !$Image->hasMoved()) {
    $imageName = $Image->getRandomName();
    $Image->move(ROOTPATH . 'public/uploads/product/', $imageName);
}

Validation works fine. When the code gets to the last line, it just won't stop writing. The file being uploaded into the product file just gets bigger and bigger. I am stumped.

Here are the request headers show in DevTools:

accept
*/*
accept-encoding
gzip, deflate
accept-language
en-US,en;q=0.9
connection
keep-alive
content-length
2654
content-type
multipart/form-data; boundary=----WebKitFormBoundarytNw7RBAAwBNUVCzh
cookie
debug-bar-theme=dark; debug-bar-position=bottom; web_session=doohnklgajb7g24mm4k036juj7jc0fd8; debug-bar-state=minimized
dnt
1
host
test.local
origin
http://test.local
referer
http://test.local/p/edit/46
user-agent
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36
x-requested-with
XMLHttpRequest

This particular file I tried uploading is only 2.3KB.

Payload in DevTools:

------WebKitFormBoundarytNw7RBAAwBNUVCzh
Content-Disposition: form-data; name="Image"; filename="download (1).jpg"
Content-Type: image/jpeg


------WebKitFormBoundarytNw7RBAAwBNUVCzh
Content-Disposition: form-data; name="ProductID"

46
------WebKitFormBoundarytNw7RBAAwBNUVCzh--

Tried changing contentType in the request to multipart/form-data explicitly and the request finishes but no file was uploaded.

2
  • 2
    content-length: 2654 from the request headers appears to match the size of the data you are uploading, and I can't spot anything wrong with the rest of it either. My guess would be that the error must be at the receiving end. Maybe try and upload towards a "vanilla" PHP script (stand-alone, no CI functionality, and not relying on CI's routing either) for testing purposes, that dumps $_POST and $_FILES for verification, and uses move_uploaded_file - and see if that also behaves wrong or not? Commented Aug 14 at 11:01
  • 1
    Very interesting one. Can you give me the value of upload_tmp_dir in php.ini? Before the move() call, dump the paths: log_message('debug', 'Temp: ' . $Image->getTempName()); log_message('debug', 'Dest: ' . ROOTPATH . 'public/uploads/product/' . $imageName); Hopefully it's not the same physical file (same path or symlink to same node). CI with the move() function reads the temporary uploaded file from getTempName() , writes it to the new location, deletes the temp file. Guessing. Just like C3roe said, a framework-independent vanilla PHP script would be good for testing. Commented Aug 15 at 19:02

2 Answers 2

0

I am not entirely sure what is causing the issue but seems to be related to the server setup.

I tried creating a fresh server in VBox with a fresh install of Ubuntu. The issue still presisted.

However, when I installed XAMPP on my Windows host machine and run the code from there, the issue is not there.

The only thing I can think of that might have caused it could be an incompatible PHP version because XAMPP PHP version is 8.2.12 and Ubuntu's version is 8.3.6.

Sign up to request clarification or add additional context in comments.

Comments

-1

You have to use the base64 string representation of the image. Please refer to the below link to check how you can use FileReader to convert the image to a data URL.

stackoverflow.com/questions/6150289/…

Then you have to convert the base64image to a physical image using your API code.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.