I'm trying to interact with GeoServer's REST API using PHP's cURL and I'm having an issue when uploading a new Shapefile...

This is my uploadShapefile method:

public function uploadShapefile($zip, $ws, $ds) {

    if (!$ws || !$ds) {
        return false;

    $fd = fopen($zip, 'rb');
    if (!$fd) {
        return false;

    $headers = ['Content-Type: application/zip'];

    $settings = [
        CURLOPT_HTTPHEADER     => $headers,
        CURLOPT_USERPWD        => $this->passwordString,
        CURLOPT_PUT            => true,
        CURLOPT_UPLOAD         => true,
        CURLOPT_REFERER        => true,
        CURLOPT_INFILE         => $fd,
        CURLOPT_INFILESIZE     => filesize($zip),

    $endpoint = "rest/workspaces/$ws/datastores/$ds/file.shp";
    $response = $this->call($endpoint, $settings);

    return $response;


My call method just uses cURL and returns the HTTP Response code

private function call($endpoint, $settings) {

    // $this->service is 'http://localhost:8080/geoserver/'
    $ch = curl_init($this->service . $endpoint);

    foreach ($settings as $setting => $value) {
        curl_setopt($ch, $setting, $value);

    // Execute
    $buffer = curl_exec($ch);

    // Result
    $info = curl_getinfo($ch);
    return $info['http_code'];

When I call the uploadShapefile method it creates the datastorage in the specified workspace, BUT its Shapefile Location under Connection Parameters is empty and it also doesn't create the new layer for the feature type.

I've checked my $fd and it can read the zip file. Am I missing something?


If I use CLI curl the behaviour is the same (datastorage created but no layer) and I get:

*   Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
* Server auth using Basic with user 'admin'
> PUT /geoserver/rest/workspaces/myworkspace/datastores/streets/file.shp HTTP/1.1
> Host: localhost:8080
> Authorization: Basic YWRtaW46Z2Vvc2VydmVy
> User-Agent: curl/7.49.1
> Accept: */*
> Content-type: application/zip
> Content-Length: 215432
> Expect: 100-continue
< HTTP/1.1 100 Continue
* We are completely uploaded and fine
< HTTP/1.1 202 Accepted
< Date: Mon, 14 Nov 2016 17:26:40 GMT
< Date: Mon, 14 Nov 2016 17:26:41 GMT
< Server: Noelios-Restlet-Engine/1.0..8
< Transfer-Encoding: chunked
* Connection #0 to host localhost left intact

1 Answer 1


Well, after many tries I discovered that this behaviour was caused by the absence of a .prj file in my zip.

So, the code is correct. It happens exactly the same in CLI's cURL.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.