Feature request: map appropriate HTTP request methods to update calls

Canisters can handle HTTP requests by providing a http_request function. However, http_request only allows making query calls.

With my PR, canisters can now also provide a function called http_request_update that allows making update calls.

When handling a HTTP request inside of http_request, if it’s necessary to make an update call, http_request can now return a response including the field upgrade with a value of true. This results in http_request_update to be called instead.

Whether any of this happens due to HTTP methods like GET or POST (or other aspects of the request) is left entirely up to the canister. I had originally inferred whether to “upgrade” from query call to update based on the HTTP method but allowing the canister to determine that explicitly is more flexible.

7 Likes

Is this live already? If not, what is the ETA? I’m eager to migrate my telegram bot to this interface and disable my own AWS-Bounday-Node (which had this feature for a year now… ;-))

1 Like

@Daniel-Bloom might know.

1 Like

@diegop do you know anything?

1 Like

No, I’ll ask around.

2 Likes

I am fairly certain this hasn’t been rolled out. I checked the update logs and I know for sure about an unrelated issue blocking production upgrades.

I will pull the built binary to ic stop gap repo. & update this thread when prod is up. (This week)

4 Likes

I use this code(feat: upgrade HTTP request calls from query to update upon canister's request by paulyoung · Pull Request #195 · dfinity/agent-rs · GitHub ) and icx-proxy (GitHub - dfinity/icx-proxy: A rust-based command line tool to serve as a gateway for a Internet Computer replica.) to test at local environment.
i try $curl -v -X POST -H “Content-type: application/json” -H “Accept: application/json” -d ‘{}’ ‘http://localhost:8000?canisterId=ai7t5-aibaq-aaaaa-aaaaa-c

But it return : Response to POST request (query)

would you tell where i get worng

That code at the top of the PR is out of date.

Basically, if http_request returns upgrade: true then http_request_update is called.

2 Likes

i just wanna know why your code can return Response to POST request ( update)
but i use you code at my computer return Response to POST request (query)

the problem is the http_requset_update didn’t work

When I posted that code sample, the code in the PR inferred which function to call based on the HTTP method.

The code that eventually got merged requires explicitly opting-in by providing upgrade = true; in the response.

Great to see that this is available now! I just got a grant (thanks DFINITY!) to finish Videate, my video podcast hosting platform. It needs to track users’ downloads, so requests for the video files will need to be upgraded to record the fact that the user downloaded a video. Looking forward to implementing this!

1 Like

So the same request will update the counter and return the video? Not sure if returning large volumes of data via update calls is a good idea, but the current interface doesn’t allow “return this data from a query, and also perform an update”.

A nice way out is to upgrade to an update call, then return a HTTP redirection, and then serve the data with a query call. You can protect the redirected URL using a magic cookie (based on a hash of a secret and a timestamp) to prevent people from using the query-URl directly.

1 Like

I haven’t been able to get IC streaming of large files working (see this thread), so my plan is to redirect the user to the file on an external CDN after making the update on the IC.

You’re right, though. Either way I’ll have to look into a solution like a magic cookie to prevent unwanted downloads. Not sure how I’d do that with an external CDN…

2 Likes

What are your issues with streaming large files? Is it 206 partial responses? If so see this thread: Boundary node http response headers

Basically in the long run the platform should be able to provide partial response capabilities for us (through the boundary nodes), but once they allow Range headers to pass through the boundary node whitelist I have a fork of the certified-assets canister that implements range requests.

I’m waiting on this for podcast audio hosting on the IC to work better (though it works now if users download the podcasts).

Hey @paulyoung, I’m really looking forward to http_request_update. How is it currently, can I use it on mainnet?

Hey @paulyoung,I see it has been merged into icx-proxy. But I use the following method to deploy on the main network, but it doesn’t work. Do I need to do anything else? Or must it only be used in icx-proxy?

  public query func http_request(request : HttpRequest) : async HttpResponse {
    {
      status_code = 200;
      headers = [];
      body = Text.encodeUtf8("Response to " # request.method # " request (query)");
      streaming_strategy = null;
    };
  };

  public shared func http_request_update(request : HttpRequest) : async HttpResponse {
    {
      status_code = 200;
      headers = [];
      body = Text.encodeUtf8("Response to post" # request.method # " request (update)");
      streaming_strategy = null;
    };
  };

@HelloRickey this was the last I heard:

So, it may be live but I haven’t gotten around to trying it myself yet.

The response you return from http_request needs to include upgrade = true; in order for http_request_upgrade to be called.

@paulyoung thanks for your reply,If it is live,the correct way to call is to add the HttpResponse in http_request,upgrade = true, then when I use post request, will receive the content of post request in http_request_update?

   public query func http_request(request : HttpRequest) : async HttpResponse {
     {
       upgrade = true; //enable http_request_update to take effect
       status_code = 200;
       headers = [];
       body = Text.encodeUtf8("Response to " # request.method # " request (query)");
       streaming_strategy = null;
     };
   };


Yes, but not necessarily for a POST request; for any request where you initially responded with upgrade = true;

1 Like