Ignore:
Timestamp:
Feb 10, 2013, 6:33:04 PM (9 years ago)
Author:
jordan
Message:

In Web Client, use jQuery.ajax() to upload files

If we use FormData? and jQuery.ajax() calls to upload a torrent,
we can stop bundling the jquery.form.js module. In addition, this
simplifies passing arguments in the headers s.t. rpc-server.c doesn't
have to look for the CSRF token as one of the multiparts.

This changes the upload POST behavior, so give it a new name (upload2).
The old function (upload) will be deprecated but kept until 2.90 so
that third-party web clients using the old POST semantics will have
time to update.

Bug #5290 <https://trac.transmissionbt.com/ticket/5290>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/rpc-server.c

    r13934 r14005  
    300300}
    301301
     302/***
     303****
     304***/
     305
     306static void
     307handle_rpc_from_json (struct evhttp_request * req,
     308                      struct tr_rpc_server  * server,
     309                      const char            * json,
     310                      size_t                  json_len);
     311
     312static void
     313handle_upload2 (struct evhttp_request * req,
     314                struct tr_rpc_server  * server)
     315{
     316  if (req->type != EVHTTP_REQ_POST)
     317    {
     318      send_simple_response (req, 405, NULL);
     319    }
     320  else
     321    {
     322      const char * val;
     323      tr_variant top;
     324      tr_variant * args;
     325      char * json;
     326      int json_len;
     327
     328      tr_variantInitDict (&top, 2);
     329      tr_variantDictAddStr (&top, TR_KEY_method, "torrent-add");
     330      args = tr_variantDictAddDict (&top, TR_KEY_arguments, 3);
     331
     332      if ((val = evhttp_find_header (req->input_headers, "X-Transmission-Add-Paused")))
     333        tr_variantDictAddBool (args, TR_KEY_paused, !tr_strcmp0(val,"true"));
     334
     335      if ((val = evhttp_find_header (req->input_headers, "X-Transmission-Add-Download-Dir")) && *val)
     336        tr_variantDictAddStr (args, TR_KEY_download_dir, val);
     337
     338      if ((val = evhttp_find_header (req->input_headers, "X-Transmission-Add-URL")) && *val)
     339        {
     340          tr_variantDictAddStr (args, TR_KEY_filename, val);
     341        }
     342      else
     343        {
     344          int i;
     345          int n;
     346          bool have_source = false;
     347          tr_ptrArray parts = TR_PTR_ARRAY_INIT;
     348
     349          extract_parts_from_multipart (req->input_headers, req->input_buffer, &parts);
     350          n = tr_ptrArraySize (&parts);
     351          for (i=0; !have_source && i<n; ++i)
     352            {
     353              tr_variant test;
     354              const struct tr_mimepart * p = tr_ptrArrayNth (&parts, i);
     355              if (!tr_variantFromBenc (&test, p->body, p->body_len))
     356                {
     357                  char * b64 = tr_base64_encode (p->body, p->body_len, NULL);
     358                  tr_variantDictAddStr (args, TR_KEY_metainfo, b64);
     359                  have_source = true;
     360                  tr_free (b64);
     361                  tr_variantFree (&test);
     362                }
     363            }
     364          tr_ptrArrayDestruct (&parts, (PtrArrayForeachFunc)tr_mimepart_free);
     365        }
     366
     367      json = tr_variantToStr (&top, TR_VARIANT_FMT_JSON, &json_len);
     368      handle_rpc_from_json (req, server, json, json_len);
     369      tr_free (json);
     370      tr_variantFree (&top);
     371    }
     372}
     373
    302374static const char*
    303375mimetype_guess (const char * path)
     
    542614}
    543615
    544 
    545 static void
    546 handle_rpc (struct evhttp_request * req, struct tr_rpc_server  * server)
    547 {
    548   struct rpc_response_data * data = tr_new0 (struct rpc_response_data, 1);
    549 
     616static void
     617handle_rpc_from_json (struct evhttp_request * req,
     618                      struct tr_rpc_server  * server,
     619                      const char            * json,
     620                      size_t                  json_len)
     621{
     622  struct rpc_response_data * data;
     623
     624  data = tr_new0 (struct rpc_response_data, 1);
    550625  data->req = req;
    551626  data->server = server;
    552627
    553   if (req->type == EVHTTP_REQ_GET)
    554     {
    555       const char * q;
    556       if ((q = strchr (req->uri, '?')))
    557         tr_rpc_request_exec_uri (server->session, q+1, -1, rpc_response_func, data);
    558     }
    559   else if (req->type == EVHTTP_REQ_POST)
    560     {
    561       tr_rpc_request_exec_json (server->session,
    562                                 evbuffer_pullup (req->input_buffer, -1),
    563                                 evbuffer_get_length (req->input_buffer),
    564                                 rpc_response_func, data);
    565     }
    566 
     628  tr_rpc_request_exec_json (server->session, json, json_len, rpc_response_func, data);
     629}
     630
     631static void
     632handle_rpc (struct evhttp_request * req, struct tr_rpc_server  * server)
     633{
     634  const char * q;
     635
     636  if (req->type == EVHTTP_REQ_POST)
     637    {
     638      handle_rpc_from_json (req, server,
     639                            (const char *) evbuffer_pullup (req->input_buffer, -1),
     640                            evbuffer_get_length (req->input_buffer));
     641    }
     642  else if ((req->type == EVHTTP_REQ_GET) && ((q = strchr (req->uri, '?'))))
     643    {
     644      struct rpc_response_data * data = tr_new0 (struct rpc_response_data, 1);
     645      data->req = req;
     646      data->server = server;
     647      tr_rpc_request_exec_uri (server->session, q+1, -1, rpc_response_func, data);
     648    }
     649  else
     650    {
     651      send_simple_response (req, 405, NULL);
     652    }
    567653}
    568654
     
    645731          handle_web_client (req, server);
    646732        }
    647       else if (!strncmp (req->uri + strlen (server->url), "upload", 6))
     733      else if (!strcmp (req->uri + strlen (server->url), "upload"))
    648734        {
    649735          handle_upload (req, server);
     
    670756        }
    671757#endif
     758      else if (!strcmp (req->uri + strlen (server->url), "upload2"))
     759        {
     760          handle_upload2 (req, server);
     761        }
    672762      else if (!strncmp (req->uri + strlen (server->url), "rpc", 3))
    673763        {
Note: See TracChangeset for help on using the changeset viewer.