Request-URI Too Long

Jump to solution
nschutz
Community Contributor

We need to replace a line that is included in all of our content pages. While testing out my PHP/cURL code that goes through each page of the course, gets the body of the page, finds and replaces the string within the body and sends the new body string to the PUT request, most of the pages worked and the old string was replaced with the new string. However, for some of the really long pages, I got this error below:

Request-URI Too Long

The requested URL's length exceeds the capacity limit for this server.


Apache Server at canvas.instructure.com Port 80

Is there any way to get around this 414 error? If not, what else can we do to mass update all content pages?

Labels (1)
3 Solutions
robotcars
Community Champion

My first thought for trouble shooting would be to ensure that you are using HTTP Method PUT, sometimes POST, for sending data to the API and that you are passing data, and not using GET and appending the data to the URL query string. The body of some wiki pages can be quite lengthy, often over 8000 characters for longer content. I've noticed when I've improperly set the length of database columns for Canvas Data. URL's like to be around 2000 characters max with various exceptions.

PUT - Syllabus Body - Courses - Canvas LMS REST API Documentation 

PUT - Updating/Create a Page Pages - Canvas LMS REST API Documentation 

POST Creating a Page - Pages - Canvas LMS REST API Documentation 

View solution in original post

James
Community Champion

 @nschutz ,

carroll-ccsd  comments reminded me that there are two ways to send the payload with PUT. You can make it part of the Query String attached to the end of the URL or you can include it as part of the post like you would with a POST. With something long like an entire wiki page, you would definitely want to use the post approach and not as part of the URL. The URL itself is really short, most of it is in the CURLOPT_POSTFIELDS. The examples from the API that Robert linked to show the body of the cURL as the -d option rather than in the URL itself.

In my PHP, I have something like this for a PUT statement. I'm using JSON to encode the object. This is pieced together from several different blocks, so hopefully I got it all.

// $options is the JSON object to send
// $url is the URL
// $token is the API access token
$data_string = json_encode( $options );
$http_headers = array (
  'Authorization: Bearer ' . $token,
  'Content-Type: application/json',
  'Content-Length: ' . strlen( $data_string )
);
$ch = curl_init( $url );
curl_setopt_array( $ch, array (
  CURLOPT_HTTPHEADER => $http_headers,
  CURLOPT_RETURNTRANSFER => TRUE,
  CURLOPT_VERBOSE => FALSE,
  CURLOPT_HEADER => TRUE,
  CURLOPT_CUSTOMREQUEST => 'PUT',
  CURLOPT_POSTFIELDS => $data_string
) );
$response = curl_exec( $ch );‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

You might also need to add a header of 'Accept: application/json' and there is obviously some additonal logic that needs included, I was just trying to get the part about the PUT statement to work.

View solution in original post

nschutz
Community Contributor

Thanks so much, Robert! I was already using PUT request, however using the PHP/cURL code generated from Postman is the problem - it sends all data on the URL string by default. I added the following line, removed the param from the url and it now runs correctly. The $newPageBody was the data being too long sometimes if passed in on the URL. 

curl_setopt_array($curl, array(
CURLOPT_URL => $updatePageURL,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => array(
'wiki_page[body]' => $newPageBody
),
CURLOPT_HTTPHEADER => array(
"Authorization: Bearer xxxxxx",
"cache-control: no-cache"
),
));

View solution in original post