Jump to content
Bob Baudewyns

Updating a JSON file with THTTPClient

Recommended Posts

Hi,

To drive my application, I am downloading at startup a JSON structure from a file located on a server.

I need to share that file between me and a remote person.

 

I am doing that successfully with the following code:

function GetJSONFromServer(const Filename: string): TJSONObject;
var
  FullURLPath: string;
  Buffer: TStringStream;
  Client: THTTPClient;
  Response: IHTTPResponse;
begin
  Result:= nil;
  Buffer := TStringStream.Create;
  try
    Client := THTTPClient.Create;
    try
      FullURLPath:= Concat(URL, '/', Filename);
      Response:= Client.Options(FullURLPath, nil, 0);
      if Response.GetStatusCode = 200 then
        begin
          Client.Get(FullURLPath, Buffer);
          if (Buffer.Size > 0) then
            Result:= TJSONObject.ParseJSONValue(Buffer.DataString) as TJSONObject
          else
            Log('ERROR: JSON File is empty !', ErrorColor);
        end
      else
        Log('ERROR: File does not exist on server !', ErrorColor);
    finally
      Client.Free();
    end;
  finally
    Buffer.Free();
  end;
end;

I'm simply trying to do the opposite: Updating the same JSON file at shutdown.

The following code doesn't generate any error but the file is not updated.

function PostJSONToServer(const Filename: string; const JSONObject: TJSONObject): Boolean;
var
  FullURLPath: string;
  Buffer: TStringStream;
  Client: THTTPClient;
  Response: IHTTPResponse;
begin
  Result:= false;
  Buffer := TStringStream.Create;
  try
    Client := THTTPClient.Create;
    try
      FullURLPath:= Concat(URL, '/', Filename);
      Response:= Client.Options(FullURLPath, nil, 0);
      if Response.GetStatusCode = 200 then
        begin
          Buffer.Seek(0, soFromBeginning);
          Buffer.WriteString(JSONObject.ToString);
          Client.Post(FullURLPath, Buffer);
          if Response.GetStatusCode = 200 then
            begin
              Log('Transaction with server successfull !', OkColor);
              Result:= true;
            end
          else
            Log('ERROR: Transaction with server failed !', ErrorColor);
        end
      else
        Log('ERROR: File does not exist on server !', ErrorColor);
    finally
      Client.Free();
    end;
  finally
    Buffer.Free();
  end;
end;

The buffer contents before posting is correct.

  • Is my code completely wrong ?
  • Should I use another query instead of Post ? 
  • Is it a matter of security preventing me to modify the file ?
  • Is there a workaround to allow such transaction ?

Thanks

Share this post


Link to post

What is written in the documentation for the server how to upload that file?

 

If the request succeeds, what is in the response content?

Share this post


Link to post

Maybe you think of FTP, but HTTP does not work this way. You need a receiver script / application on your web server which will receive and save that file.

  • Like 1

Share this post


Link to post
4 hours ago, Bob Baudewyns said:

I don't want to upload the file.

I want to update the content of that file on the server

That's basically the same.

 

Just imagine, the file is not existent, but the server produces the content on the fly. The result from a GET would be the same. How do you think could you change such a response?

Share this post


Link to post

There is absolutely no server action here. Sorry for the confusion.

 

Let's say it's a remote file instead of a file stored on each local computer

The file is just sitting there to be shared between computers and potentially modified by one of these computers

Imagine this is a configuration JSON file driving the behavior of each computer. But can be changed and affecting all computers that are reading it at startup 

 

My question is focusing if I can change that file by code without downloading and uploading it.

If I can get the content of the file with THTTPClient.Get, why I couldn't change that content with POST or PUT ?

 

Share this post


Link to post
1 hour ago, Bob Baudewyns said:

If I can get the content of the file with THTTPClient.Get, why I couldn't change that content with POST or PUT ?

Because POST and PUT need some appropriate server action to achieve the desired result. The web server implementation resolves a GET to an existing file by providing the file content just as it were a static HTML page. On the other side there is no standard implementation to update, replace or create the file via POST or PUT. This feature has to be implemented to be used. Imagine every user accessing your web server could change the static web pages by simply calling PUT or POST.

 

The standard solution for your problem would be using FTP. An FTP server has separate access control and allows writing on a per user/folder/file basis.

Share this post


Link to post

HTTP sometimes mimics file structure but it isn't, that's why the confusion. Request for "example.com/foo.bar" could be handled by server as "print("this is foo.bar") executed on-the-fly. "example.com/goods/shoes/male" could turn into "DB select from goods where cat=shoes and sex=male". So you need proper URLs (sometimes called endpoints) to execute upload. It's possible they're implemented as "example.com/file.ext" but usually they look like "example.com/upload"

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×