diff --git a/doc/api/http_api.md b/doc/api/http_api.md index 7599fae00..2105e4fde 100644 --- a/doc/api/http_api.md +++ b/doc/api/http_api.md @@ -67,7 +67,28 @@ The current version can be queried via /api. ### Request Format -The API is accessible via HTTP. HTTP Requests are in the format /api/$APIVERSION/$FUNCTIONNAME. Parameters are transmitted via HTTP GET. $APIVERSION depends on the endpoints you want to use. +The API is accessible via HTTP. Starting from **1.8**, API endpoints can be invoked indifferently via GET or POST. + +The URL of the HTTP request is of the form: `/api/$APIVERSION/$FUNCTIONNAME`. $APIVERSION depends on the endpoint you want to use. Depending on the verb you use (GET or POST) **parameters** can be passed differently. + +When invoking via GET (mandatory until **1.7.5** included), parameters must be included in the query string (example: `/api/$APIVERSION/$FUNCTIONNAME?apikey=¶m1=value1`). Please note that starting with nodejs 8.14+ the total size of HTTP request headers has been capped to 8192 bytes. This limits the quantity of data that can be sent in an API request. + +Starting from Etherpad **1.8** it is also possible to invoke the HTTP API via POST. In this case, querystring parameters will still be accepted, but **any parameter with the same name sent via POST will take precedence**. If you need to send large chunks of text (for example, for `setText()`) it is advisable to invoke via POST. + +Example with cURL using GET (toy example, no encoding): +``` +curl "http://pad.domain/api/1/setText?apikey=secret&padID=padname&text=this_text_will_NOT_be_encoded_by_curl_use_next_example" +``` + +Example with cURL using GET (better example, encodes text): +``` +curl "http://pad.domain/api/1/setText?apikey=secret&padID=padname" --get --data-urlencode "text=Text sent via GET with proper encoding. For big documents, please use POST" +``` + +Example with cURL using POST: +``` +curl "http://pad.domain/api/1/setText?apikey=secret&padID=padname" --data-urlencode "text=Text sent via POST with proper encoding. For big texts (>8 KB), use this method" +``` ### Response Format Responses are valid JSON in the following format: @@ -278,7 +299,9 @@ returns the text of a pad #### setText(padID, text) * API >= 1 -sets the text of a pad +Sets the text of a pad. + +If your text is long (>8 KB), please invoke via POST and include `text` parameter in the body of the request, not in the URL (since Etherpad **1.8**). *Example returns:* * `{code: 0, message:"ok", data: null}` @@ -288,7 +311,9 @@ sets the text of a pad #### appendText(padID, text) * API >= 1.2.13 -appends text to a pad +Appends text to a pad. + +If your text is long (>8 KB), please invoke via POST and include `text` parameter in the body of the request, not in the URL (since Etherpad **1.8**). *Example returns:* * `{code: 0, message:"ok", data: null}` @@ -309,6 +334,8 @@ returns the text of a pad formatted as HTML sets the text of a pad based on HTML, HTML must be well-formed. Malformed HTML will send a warning to the API log. +If `html` is long (>8 KB), please invoke via POST and include `html` parameter in the body of the request, not in the URL (since Etherpad **1.8**). + *Example returns:* * `{code: 0, message:"ok", data: null}` * `{code: 1, message:"padID does not exist", data: null}` diff --git a/src/node/hooks/express/apicalls.js b/src/node/hooks/express/apicalls.js index d6011c97f..cf4507480 100644 --- a/src/node/hooks/express/apicalls.js +++ b/src/node/hooks/express/apicalls.js @@ -40,7 +40,7 @@ exports.expressCreateServer = function (hook_name, args, cb) { //This is a api POST call, collect all post informations and pass it to the apiHandler args.app.post('/api/:version/:func', function(req, res) { new formidable.IncomingForm().parse(req, function (err, fields, files) { - apiCaller(req, res, fields) + apiCaller(req, res, Object.assign(req.query, fields)) }); }); diff --git a/tests/backend/specs/api/pad.js b/tests/backend/specs/api/pad.js index 26abfd2c8..4a0c6b6a2 100644 --- a/tests/backend/specs/api/pad.js +++ b/tests/backend/specs/api/pad.js @@ -387,7 +387,8 @@ describe('createPad', function(){ describe('setText', function(){ it('Sets text on a pad Id', function(done) { - api.get(endPoint('setText')+"&padID="+testPadId+"&text="+text) + api.post(endPoint('setText')+"&padID="+testPadId) + .send({text: text}) .expect(function(res){ if(res.body.code !== 0) throw new Error("Pad Set Text failed") }) @@ -410,7 +411,8 @@ describe('getText', function(){ describe('setText', function(){ it('Sets text on a pad Id including an explicit newline', function(done) { - api.get(endPoint('setText')+"&padID="+testPadId+"&text="+text+'%0A') + api.post(endPoint('setText')+"&padID="+testPadId) + .send({text: text+'\n'}) .expect(function(res){ if(res.body.code !== 0) throw new Error("Pad Set Text failed") })