Cannot Load App - when passing a long string to "/new-topic?" API


(Daler) #1

I’m consistently getting the Cannot Load App error page when passing a long string to create a new post via URL API as:
My.site/new-topic?title=Some+Title&body=Some+Long+Body

Sometimes I get these errors (for the same request):

Failed to load resource: net::ERR_CONNECTION_CLOSED
The FetchEvent for "https://...." resulted in a network error response: an object that was not a Response was passed to respondWith().
GET "https://..." net::ERR_FAILED

Can somebody please help me understand and fix this issue?

I’ve tried shortening the payload strings and such request to my server successfully loads the composer with title and body strings getting passed properly into Composer.

Context:
I have a recent standard installation of Discourse ( on Ubuntu 17.x VPS, 12 GB RAM, 4 nice cores,
only Discourse, single container).

I’ve uninstalled the 3 plugins I had (even the Docker-manager) one by one and rebuilt the app several times to see if the issue can be related to some plugin, but the issue persisted even with no plugins installed.

Tested on several forums:

Here’s example which cannot load the app - EDIT: this link surprisingly works if clicked, but doesn’t load if copy+pasted into browser.

The same string passed to this meta-forum successfully loads the app (composer).


(Blake Erickson) #2

Can you try an API request where the new topic contents are in the POST body and not in the url?

See Discourse API Docs for the new topic api details.


(Jeff Atwood) #3

This implies Nginx, or somewhere else in the upstream networking stack, is objecting to that super long URL. It cannot, by definition, be a bug in Discourse if it works here.


(Daler) #4

@blake Thanks! I briefly looked at making a POST request and apologize if I misunderstood something, but my goal is to let a user edit their post before actually posting to our forum (when sharing a web content with our bookmarklet).

I understand they can edit after posting, but that’s not the UX I’m trying to achieve.

@codinghorror I agree, so posting here or in #howto:sysadmin seemed more appropriate than in #bug

I’m trying to understand what could be the issue. I only followed the standard (simple) installation of Discourse and didn’t make any custom configs to Nginx or the OS.

Appreciate any hints. :slight_smile:


(Blake Erickson) #5

You are having this issue because you are using the default nginx config. You most likely will need to change something in your nginx config that will allow for much larger urls.


(Blake Erickson) #6

I wonder if you could send a POST request to /draft.json and then just pop open the composer window somehow and achieve the same thing?


(Daler) #7

Can you point to some Discourse-related examples of how to do it properly in the context of this issue? (I’m pretty new to Nginx configs)

I tried the simplest way to test this suggestion via browser console (being logged into the forum) as: $.post('draft.json', { "title":"test", "topic_id": 0, "raw": "mytest" }) and both here on meta and on my forum it consistently returns POST 500 error.

How do you do it and what do you get?


(Daler) #8

I’m still trying to figure out the proper way to start creating a new topic via "/new-topic?" or draft.json API and any advice is very appreciated.

Which way should I go and what implications (in terms of performance and security) should I keep in mind?

A) Allow longer URLs with Nginx like suggested here or somehow allow longer query strings?
Yet, it isn’t very clear how a pups template should look like for such purpose.

B) Make a POST request. How?
Tried making a post request (as per docs), but that returns 422 error:

url = 'https://my.site/posts'
data = '{"title":"Title must be long enough","topic_id": 0,"raw": "body of post must be long enough"}'
$.post( url, data )

(Blake Erickson) #9

Is the code you currently have to open the composer running on your Discourse forum or an external site that links to your Discourse forum?


(Daler) #10

Just to reiterate (not trying to be rude :slight_smile: ):

 function submitContent($, title, markdown, showFrame) {
        var $form = $("<form>")
            .attr("method", "get")
            .attr("action", FORUM_URL)
            .append($("<input name=title>").val(title))
            .append($("<input name=category>").val(CATEGORY))
            .append($("<textarea name=body>").val(markdown))    // Textarea preserves line breaks
            .append($("<input name=showframe>").val(showFrame))
            .appendTo('body');
        $form.submit();
    }

So, in the above case the code runs in user’s browser (on some arbitrary external webpage) and passes the data to https://oprium.com/new-topic? via GET request (triggering the Composer). Using POST request didn’t work.

I’m considering to modify the bookmarklet code to make a POST request, but I’m not sure how to do that properly and trigger opening the Composer and passing the data to pre-fill the Title, Body and Category fields.

Sorry if I misunderstood your question and thanks for looking here.


(Blake Erickson) #11

Oh yea thanks, I thought it was from a bookmarklet, but I couldn’t find it in the original post. Thanks for quoting it.

The easiest route is to modify your nginx config like the pups link mentions. It basically is doing a search and replace like in this example discourse_docker/web.ratelimited.template.yml at master · discourse/discourse_docker · GitHub

If I had to figure out how to do this I would ssh into your box and look at your actual nginx config and find a specific string in your config that I could then append the change to. That line you will use in the “from” and the “to” sections.

Then I would open up one of the template.yml files and add a

 run:
   replace:
   filename:
   from:
   to:

block and fill it out. Then you need to rebuild your app. You might want to test this out on another test forum so your don’t break your actual site. Give that a shot and let us know how far you get.

To test it out though you can add your change to the actual nginx config file and it will persist until the container is rebuilt. So you can see if your change is working first and then try and add it the pups way to make it permanent.

Sorry didn’t mean to lead you down the wrong path with the POST request. That should work but can be tricky cause of cookies and CORS issues.


(Daler) #12

Ok, (to test things) here’s what I tried with no success (using ./launcher enter app on my server):

  1. in my /etc/nginx/conf.d/discourse.conf found this line (#11):
    proxy_buffer_size 8k;
    and added the following to allow large URIs:
    client_header_buffer_size 64k;
    large_client_header_buffers 4 64k;
    
  2. Tried to enforce new configs for Nginx without restart like:
    sudo kill -HUP (nginx pid) then also nginx -s reload

Nothing has changed. What am I doing wrong?