Feature request: map appropriate HTTP request methods to update calls

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

Hey @faraz.shaikh , Do you know the latest developments in HTTP request methods to update calls?

Hey,

Apologies for the delayed response on this one. The latest boundary node deployment was done on March 1st 2022. The production deployment now reflects the state of the icx-proxy repo on 1st March.

So this feature is live in production. Please report if something is amiss.

cc: @Daniel-Bloom

Thanks
Faraz

3 Likes

Exciting! I will try to port my telegram bot when I find the time, and will report back.

Can it be used in canister? I found that http_request_update still did not take effect.

@paulyoung, I assume you didn’t change the service worker, just icx-proxy, right?

This means that this feature only works on the raw URLs for now, not the certified ones where the service worker locally translates HTTP to IC calls. Just a heads up for people testing this feature.

(Maybe it was a mistake to use the agent in the service worker, and it should instead go via raw HTTP, to separate concerns more cleanly, and also benefit from caching on the boundary nodes?)

I didn’t. I think at first it hadn’t been open-sourced. I’m not sure if it had at the time of merging but I wasn’t getting much input on how to go about it.

I tried to call attention to it here: feat: upgrade HTTP calls upon canister's request by paulyoung · Pull Request #6 · dfinity/icx-proxy · GitHub

and later left a note for myself here: feat: upgrade HTTP calls upon canister's request by paulyoung · Pull Request #6 · dfinity/icx-proxy · GitHub

1 Like

I did a quick test with the Motoko playground:

And it works! If you go to https://y4oop-liaaa-aaaab-qacha-cai.raw.ic0.app/ it loads kinda slowly (yay for consensus) and keeps counting the requests. Probably the canister will disappear after a while. Maybe I should host the demo permanently…

6 Likes

Thanks for the example! This is huge! Quick question, is there a way to pass in authentication headers so that message.caller set?

Something like return_and_upgrade would be great for tracking statistics.