View random ngrok URL when run in background - ngrok
When I start an ngrok client with ./ngrok tcp 22 it runs in the foreground and I can see the randomly generated forwarding URL, such as tcp://0.tcp.ngrok.io:12345 -> localhost:22.
If I run in it the background with ./ngrok tcp &, I can't find any way to see the forwarding URL. How can I run ngrok in the background and still see the URL?
There are a couple of ways.
You can either:
1) Visit localhost:4040/status in your browser to see a bunch of information, or
2) Use curl to hit the API: localhost:4040/api/tunnels
This little Python (2.7) script will call the ngrok API and print the current URL's:
import json
import os
os.system("curl http://localhost:4040/api/tunnels > tunnels.json")
with open('tunnels.json') as data_file:
datajson = json.load(data_file)
msg = "ngrok URL's: \n'
for i in datajson['tunnels']:
msg = msg + i['public_url'] +'\n'
print (msg)
If you want to get the first tunnel then jq will be your friend:
curl -s localhost:4040/api/tunnels | jq -r .tunnels[0].public_url
When running more than one instance of ngrok then use the tunnel name /api/tunnels/:name.
Run ./ngrok http & This runs the ngrok tunnel as a background process. Ngrok usually opens a window showing the assigned URL but since we are using the nohup command this is not visible.
Thus, then run curl http://127.0.0.1:4040/api/tunnels too see the URL assigned by ngrok
If it helps anyone I wrote a quick script to extract the generated random url in Node:
It makes assumption you're only interested in the secure url.
const fetch = require('node-fetch')
fetch('http://localhost:4040/api/tunnels')
.then(res => res.json())
.then(json => json.tunnels.find(tunnel => tunnel.proto === 'https'))
.then(secureTunnel => console.log(secureTunnel.public_url))
.catch(err => {
if (err.code === 'ECONNREFUSED') {
return console.error("Looks like you're not running ngrok.")
}
console.error(err)
})
If you wanted all tunnels:
const fetch = require('node-fetch')
fetch('http://localhost:4040/api/tunnels')
.then(res => res.json())
.then(json => json.tunnels.map(tunnel => tunnel.public_url))
.then(publicUrls => publicUrls.forEach(url => console.log(url)))
.catch(err => {
if (err.code === 'ECONNREFUSED') {
return console.error(
"Looks like you're not running ngrok."
)
}
console.error(err)
})
import json
import requests
def get_ngrok_url():
url = "http://localhost:4040/api/tunnels/"
res = requests.get(url)
res_unicode = res.content.decode("utf-8")
res_json = json.loads(res_unicode)
for i in res_json["tunnels"]:
if i['name'] == 'command_line':
return i['public_url']
break
This is an edit of JUN_NETWORKS python 3 code. It outputs the HTTPS URL only. I find Ngrok will randomly change the order of which is URL is displayed first sometimes outputting HTTP. The additional loop will consistently look for the 'tunnel' named 'command_line' which is the HTTPS URL.
The easiest way for me to check random generated URL is to go to ngrok official site > dashboard > endpoints > status and check the URLs and status of my endpoints
In Python3
import json
import requests
def get_ngrok_url():
url = "http://localhost:4040/api/tunnels"
res = requests.get(url)
res_unicode = res.content.decode("utf-8")
res_json = json.loads(res_unicode)
return res_json["tunnels"][0]["public_url"]
This returned json have 2 url for http and https.
If you want only https url, you res_json["tunnels"][index num]["proto"]
If you love PowerShell, here it is in variables.
$ngrokOutput = ConvertFrom-Json (Invoke-WebRequest -Uri http://localhost:4040/api/tunnels).Content
$httpsUrl = $ngrokOutput.tunnels.public_url[0]
$httpUrl = $ngrokOutput.tunnels.public_url[1]
Use the ngrok API to get all active URLs
You will need to generate a token first (https://dashboard.ngrok.com/api)
Then fetch the active endpoints from the API
curl \
-H "Authorization: Bearer {API_KEY}" \
-H "Ngrok-Version: 2" \
https://api.ngrok.com/endpoints
check documentation: https://ngrok.com/docs/api/resources/endpoints
In Ruby
require 'httparty'
# get ngrok public url
begin
response = HTTParty.get 'http://localhost:4040/api/tunnels'
json = JSON.parse response.body
new_sms_url = json['tunnels'].first['public_url']
rescue Errno::ECONNREFUSED
print 'no ngrok instance found. shutting down'
exit
end
A Node.js solution.
Bonus: It copies the url to the clipboard in Windows, Mac and Linux1
const http = require("http");
const { execSync } = require("child_process");
const callback = (res) => {
let data = "";
res.on("data", (chunk) => (data += chunk));
res.on("end", () => {
const resJSON = JSON.parse(data);
const tunnels = resJSON.tunnels;
const { public_url: url } = tunnels.find(({ proto }) => proto === "https");
console.log(url);
// Copy to clipboard
switch (process.platform) {
case "win32":
execSync(`echo ${url} | clip`);
break;
case "darwin":
execSync(`echo ${url} | pbcopy`);
break;
case "linux":
// NOTE: this requires xclip to be installed
execSync(`echo ${url} | xclip -selection clipboard`);
break;
default:
break;
}
});
};
http.get("http://localhost:4040/api/tunnels", callback);
[1] You need to install xclip first:
sudo apt-get install xclip
If you're using nodejs I did this
const getURL = async () => {
// inspect if the callback is working at: http://127.0.0.1:4040/inspect/http
const ngrok = await import('ngrok')
const api = ngrok.getApi();
const { tunnels } = JSON.parse(await api?.get('api/tunnels') ?? '{}')
// if we already have a tunnel open, disconnect. We're only allowed to have 4
if (tunnels?.length > 0) await ngrok.disconnect()
return await ngrok.connect(3000)
}
May be I'm a little too late in answering but would be glad if it is helpful for anyone visiting the question.
***Above answers are solutions to see/check the redirection URL. However to run ngrok in background, you could try using screen in linux . Incase you need help here a quick reference
Steps:
1. Just run the ngrok in screen and then detach.
2. Use the python script given by Gerard above to see the URL.
I have followed the same process and it works!
There is a better way to do that just login to your account on ngrok.com.
Your URL will be in your dashboard.
Related
Firebase: Error (auth/unauthorized-domain) on localhost
I'm getting Firebase: Error (auth/unauthorized-domain) on localhost during google auth. I found that this error is caused when domain is not added to Authorized domains in Firebase. But when i checked Authorized domains there is localhost, and don't know who is causing this error... ` const signInWithGoogle = () => { const provider = new GoogleAuthProvider() signInWithPopup(getAuth(), provider) .then((result) => { console.log(result.user) router.push("/login") }) .catch((error) => { console.log(error) alert(error.body + ": " + error.message) }) } `
If it is a Vite Project. Add 1 . import dns from 'dns' 2 . dns.setDefaultResultOrder('verbatim') command in vite.config.js run ''' npm run dev ''' it will give you the link to localhost in your terminal to open your app and run it. It will work for sure. Many thanks for considering my request.
As mentioned above, the url to visit is localhost/ not 127.0.0.1 as that is a different domain than localhost/ although it is effectively the same to your machine.
Serving files on a local network with Deno
I recently decided to play around with Deno a bit. Right now I am trying to set up a basic file server on my local network, but it will only serve files to my computer and not the rest of the network (I can't even send a http request to the server from outside my computer). I can not, for the life of me, figure out why it only works locally. I have added the code I am using at the moment below just in case, but I'm pretty sure the problem is somewhere else, because I have the same problem with this file_server example and when I create a file server with oak import { serve } from 'https://deno.land/std#v0.42.0/http/server.ts'; const server = serve({ port: 3000 }); const decoder = new TextDecoder('utf-8'); for await (const req of server) { const filePath = 'public' + req.url; try { const data = await Deno.readFile(filePath); req.respond({ body: decoder.decode(data) }); } catch (error) { if (error.name === Deno.errors.NotFound.name) { console.log('File "' + filePath + '" not found'); req.respond({ status: 404, body: 'File not found' }); } else { req.respond({ status: 500, body: 'Rest in pieces' }); throw error; } } } The command I'm using to run the file is: deno --allow-all server.ts When I create a simple file server in Node.js everything works just fine. It can serve files to my computer and any other device on the network. I think the fault is with my understanding of Deno and it's security concepts, but I don't know. I would greatly appreciate any help and can supply more details if required.
You need to bind the hostname to 0.0.0.0 like so : const server = serve({ hostname: '0.0.0.0', port: 3000 }); By default, your webserver only responds to localhost and 127.0.0.1. Binding to 0.0.0.0 tells Deno to bind to all IP addresses/interfaces on your machine. Which makes it accessible to any machine on your network. Your network IP address in the format of 192.168.x.y. gets also bind to the Deno webserver which allows another computer in your network to access the webserver with your local IP address.
Dynamic host in axios
How can I create a dynamic host in axios? Example: const host = location.hostname; // axios.defaults.baseURL = 'http://hastore.local'; axios.defaults.baseURL = host; axios.defaults.port = 8080; axios.get('api/categories') .then((res) => { this.categories = res.data; console.log(res); }) .catch((err) => { console.warn('error during http call', err); }); String axios.defaults.baseURL = 'http://hastore.local'; does not fit, because on prodaction don't be work. String const host = location.hostname; also not a solution, because I get incorrect port and dublicate host. The goal is to get the right host depending on the environment. I read a lot of articles about this, but I did not find a solution. Thanks for help! axios version: e.g.: v0.16.2 Environment: e.g.: node v8.9.4, chrome 64.0.3282.119, Ubuntu 16.04 Symfony 4.0.4 Vue.js 2.4.2 vue-axios 2.0.2
You probably do not need to set baseURL. Have you tried to define baseURL each time you make requests? For example, axios.get(`${host}:${port}/api/categories`) Or, depending on your words "The goal is to get the right host depending on the environment.", you may define proper host using your environment variables, for example: axios.get(`${proccess.env.HOST}:${PORT}/api/categories`) If you use a bundler for your frontend code, this expression will be resolved to axios.get('http://example.com:80/api/categories') That's because your bundler actually should run with pre-defined environment variables HOST and PORT
I found a solution. Add this code in your: /src/main.js Example: const baseURL = 'http://localhost:8080'; if (typeof baseURL !== 'undefined') { Vue.axios.defaults.baseURL = baseURL; } The answer that helped me in this: Set baseURL from .env in VueAxios Thanks everyone for help!
cloudfoundry groovy (java) app fails to read external url giving 403
https://groups.google.com/group/caelyf/feed/rss_v2_0_topics.xml in a browser window correctly returns xml stream; Using groovy in cloudfoundry app, this fails with http 403 permission failure like: def url = "https://groups.google.com/group/caelyf/feed/rss_v2_0_topics.xml:443".toURL() def tx = url.getText('UTF-8') cloudfoundry forum implies only https plus port 443 can read an external url any ideas ?
not sure why you stuck :443 on the end of the url? 403 means forbidden. I'm guessing Google doesn't let you scrape the groups site with java. you could try setting the user agent to that of a browser? def tx = url.openConnection().with { setRequestProperty("User-Agent", "Firefox/2.0.0.4") inputStream.with { def ret = getText( 'UTF-8' ) close() ret } } or similar... I don't think this is a cloudfoundry issue. have you tried running the above from your machine to confirm this? Edit: Just tried it, and it works (at least on my machine). This shows how to load the XMl into a parser, and print the titles from the feed: URL url = "https://groups.google.com/group/caelyf/feed/rss_v2_0_topics.xml".toURL() def tx = new XmlSlurper().with { x -> url.openConnection().with { // Pretend to be an old Firefox version setRequestProperty("User-Agent", "Firefox/2.0.0.4") // Get a reader inputStream.withReader( 'UTF-8' ) { // and parse it with the XmlSlurper parse( it ) } } } // Print all the titles tx.channel.item.title.each { println it }
HTTP test server accepting GET/POST requests
I need a live test server that accepts my requests for basic information via HTTP GET and also allows me to POST (even if it's really not doing anything). This is entirely for test purposes. A good example is here. It easily accepts GET requests, but I need one that accepts POST requests as well. Does anyone know of a server that I can send dummy test messages too?
https://httpbin.org/ It echoes the data used in your request for any of these types: https://httpbin.org/anything Returns most of the below. https://httpbin.org/ip Returns Origin IP. https://httpbin.org/user-agent Returns user-agent. https://httpbin.org/headers Returns header dict. https://httpbin.org/get Returns GET data. https://httpbin.org/post Returns POST data. https://httpbin.org/put Returns PUT data. https://httpbin.org/delete Returns DELETE data https://httpbin.org/gzip Returns gzip-encoded data. https://httpbin.org/status/:code Returns given HTTP Status code. https://httpbin.org/response-headers?key=val Returns given response headers. https://httpbin.org/redirect/:n 302 Redirects n times. https://httpbin.org/relative-redirect/:n 302 Relative redirects n times. https://httpbin.org/cookies Returns cookie data. https://httpbin.org/cookies/set/:name/:value Sets a simple cookie. https://httpbin.org/basic-auth/:user/:passwd Challenges HTTPBasic Auth. https://httpbin.org/hidden-basic-auth/:user/:passwd 404'd BasicAuth. https://httpbin.org/digest-auth/:qop/:user/:passwd Challenges HTTP Digest Auth. https://httpbin.org/stream/:n Streams n–100 lines. https://httpbin.org/delay/:n Delays responding for n–10 seconds.
There is http://ptsv2.com/ "Here you will find a server which receives any POST you wish to give it and stores the contents for you to review."
Webhook Tester is a great tool: https://webhook.site (GitHub) Important for me, it showed the IP of the requester, which is helpful when you need to whitelist an IP address but aren't sure what it is.
nc one-liner local test server Setup a local test server in one line under Linux: nc -kdl localhost 8000 Sample request maker on another shell: wget http://localhost:8000 then on the first shell you see the request showed up: GET / HTTP/1.1 User-Agent: Wget/1.19.4 (linux-gnu) Accept: */* Accept-Encoding: identity Host: localhost:8000 Connection: Keep-Alive nc from the netcat-openbsd package is widely available and pre-installed on Ubuntu. Tested on Ubuntu 18.04.
http://requestb.in was similar to the already mentioned tools and also had a very nice UI. RequestBin gives you a URL that will collect requests made to it and let you inspect them in a human-friendly way. Use RequestBin to see what your HTTP client is sending or to inspect and debug webhook requests. Though it has been discontinued as of Mar 21, 2018. We have discontinued the publicly hosted version of RequestBin due to ongoing abuse that made it very difficult to keep the site up reliably. Please see instructions for setting up your own self-hosted instance.
If you want a local test server that accepts any URL and just dumps the request to the console, you can use node: const http = require("http"); const hostname = "0.0.0.0"; const port = 3000; const server = http.createServer((req, res) => { console.log(`\n${req.method} ${req.url}`); console.log(req.headers); req.on("data", function(chunk) { console.log("BODY: " + chunk); }); res.statusCode = 200; res.setHeader("Content-Type", "text/plain"); res.end("Hello World\n"); }); server.listen(port, hostname, () => { console.log(`Server running at http://localhost:${port}/`); }); Save it in a file 'echo.js' and run it as follows: $ node echo.js Server running at http://localhost:3000/ You can then submit data: $ curl -d "[1,2,3]" -XPOST http://localhost:3000/foo/bar which will be shown in the server's stdout: POST /foo/bar { host: 'localhost:3000', 'user-agent': 'curl/7.54.1', accept: '*/*', 'content-length': '7', 'content-type': 'application/x-www-form-urlencoded' } BODY: [1,2,3]
Have a look at PutsReq, it's similar to the others, but it also allows you to write the responses you want using JavaScript.
Here is one Postman echo: https://docs.postman-echo.com/ example: curl --request POST \ --url https://postman-echo.com/post \ --data 'This is expected to be sent back as part of response body.' response: {"args":{},"data":"","files":{},"form":{"This is expected to be sent back as part of response body.":""},"headers":{"host":"postman-echo.com","content-length":"58","accept":"*/*","content-type":"application/x-www-form-urlencoded","user-agent":"curl/7.54.0","x-forwarded-port":"443","x-forwarded-proto":"https"},"json":{"...
You can run the actual Ken Reitz's httpbin server locally (under docker or on bare metal): https://github.com/postmanlabs/httpbin Run dockerized docker pull kennethreitz/httpbin docker run -p 80:80 kennethreitz/httpbin Run directly on your machine ## install dependencies pip3 install gunicorn decorator httpbin werkzeug Flask flasgger brotlipy gevent meinheld six pyyaml ## start the server gunicorn -b 0.0.0.0:8000 httpbin:app -k gevent Now you have your personal httpbin instance running on http://0.0.0.0:8000 (visible to all of your LAN) Minimal Flask REST server I wanted a server which returns predefined responses so I found that in this case it's simpler to use a minimal Flask app: #!/usr/bin/env python3 # Install dependencies: # pip3 install flask import json from flask import Flask, request, jsonify app = Flask(__name__) #app.route('/', methods=['GET', 'POST']) def root(): # spit back whatever was posted + the full env return jsonify( { 'request.json': request.json, 'request.values': request.values, 'env': json.loads(json.dumps(request.__dict__, sort_keys=True, default=str)) } ) #app.route('/post', methods=['GET', 'POST']) def post(): if not request.json: return 'No JSON payload! Expecting POST!' # return the literal POST-ed payload return jsonify( { 'payload': request.json, } ) #app.route('/users/<gid>', methods=['GET', 'POST']) def users(gid): # return a JSON list of users in a group return jsonify([{'user_id': i,'group_id': gid } for i in range(42)]) #app.route('/healthcheck', methods=['GET']) def healthcheck(): # return some JSON return jsonify({'key': 'healthcheck', 'status': 200}) if __name__ == "__main__": with app.test_request_context(): app.debug = True app.run(debug=True, host='0.0.0.0', port=8000)
I don't konw why all of the answers here make a very simple work very hard! When there is a request on HTTP, actually a client will send a HTTP_MESSAGE to server (read about what is HTTP_MESSAGE) and you can make a server in just 2 simple steps: Install netcat: In many unix-based systems you have this already installed and if you have windows just google it , the installation process is really simple, you just need a nc.exe file and then you should copy the path of this nc.exe file to your path environment variable and check if every thing is OK with nc -h Make a server which is listening on localhost:12345: just type nc -l -p 12345 on your terminal and everything is done! (in mac nc -l 12345 tnx Silvio Biasiol) Now you have a server which is listening on http://localhost:12345 , for example you can make a post request with axios If you are a js developer: axios.post('http://localhost:12345', { firstName: 'Fred' }) or make your own xhr or make a form in a HTML file and submit it to server, sth. like: <form action="http://localhost:12345" method="post"> or make a request with curl or wget or etc. Then check your terminal, a raw HTTP_MESSAGE should be appear on your terminal and you can start your happy hacking ;)
https://www.mockable.io. It has nice feature of getting endpoints without login (24h temporary account)
Create choose a free web host and put the following code <h1>Request Headers</h1> <?php $headers = apache_request_headers(); foreach ($headers as $header => $value) { echo "<b>$header:</b> $value <br />\n"; } ?>
I have created an open-source hackable local testing server that you can get running in minutes. You can create new API's, define your own response and hack it in any ways you wish to. Github Link : https://github.com/prabodhprakash/localTestingServer
some online httpbin: https://httpbin.org/ https://httpbingo.org/ https://quic.aiortc.org/httpbin/ get client ip, port, ua.. http://ifconfig.io/ get client ip, isp https://www.cip.cc/
If you need or want a simple HTTP server with the following: Can be run locally or in a network sealed from the public Internet Has some basic auth Handles POST requests I built one on top of the excellent SimpleHTTPAuthServer already on PyPI. This adds handling of POST requests: https://github.com/arielampol/SimpleHTTPAuthServerWithPOST Otherwise, all the other options publicly available are already so good and robust.
You might don't need any web site for that, only open up the browser, press F12 to get access to developer tools > console, then in console write some JavaScript Code to do that. Here I share some ways to accomplish that: For GET request: *.Using jQuery: $.get("http://someurl/status/?messageid=597574445", function(data, status){ console.log(data, status); }); For POST request: Using jQuery $.ajax: var url= "http://someurl/", api_key = "6136-bc16-49fb-bacb-802358", token1 = "Just for test", result; $.ajax({ url: url, type: "POST", data: { api_key: api_key, token1: token1 }, }).done(function(result) { console.log("done successfuly", result); }).fail(function(error) { console.log(error.responseText, error); }); Using jQuery, append and submit var merchantId = "AA86E", token = "4107120133142729", url = "https://payment.com/Index"; var form = `<form id="send-by-post" method="post" action="${url}"> <input id="token" type="hidden" name="token" value="${merchantId}"/> <input id="merchantId" name="merchantId" type="hidden" value="${token}"/> <button type="submit" >Pay</button> </div> </form> `; $('body').append(form); $("#send-by-post").submit();//Or $(form).appendTo("body").submit(); Using Pure JavaScript: `var api_key = "73736-bc16-49fb-bacb-643e58", recipient = "095552565", token1 = "4458", url = 'http://smspanel.com/send/';` ``var form = `<form id="send-by-post" method="post" action="${url}"> <input id="api_key" type="hidden" name="api_key" value="${api_key}"/> <input id="recipient" type="hidden" name="recipient" value="${recipient}"/> <input id="token1" name="token1" type="hidden" value="${token1}"/> <button type="submit" >Send</button> </div> </form>`;`` document.querySelector("body").insertAdjacentHTML('beforeend',form); document.querySelector("#send-by-post").submit(); Or even using ASP.Net: var url = "https://Payment.com/index"; Response.Clear(); var sb = new System.Text.StringBuilder(); sb.Append("<html>"); sb.AppendFormat("<body onload='document.forms[0].submit()'>"); sb.AppendFormat("<form action='{0}' method='post'>", url); sb.AppendFormat("<input type='hidden' name='merchantId' value='{0}'>", "C668"); sb.AppendFormat("<input type='hidden' name='Token' value='{0}'>", "22720281459"); sb.Append("</form>"); sb.Append("</body>"); sb.Append("</html>"); Response.Write(sb.ToString()); Response.End();
I am not sure if anyone would take this much pain to test GET and POST calls. I took Python Flask module and wrote a function that does something similar to what #Robert shared. from flask import Flask, request app = Flask(__name__) #app.route('/method', methods=['GET', 'POST']) #app.route('/method/<wish>', methods=['GET', 'POST']) def method_used(wish=None): if request.method == 'GET': if wish: if wish in dir(request): ans = None s = "ans = str(request.%s)" % wish exec s return ans else: return 'This wish is not available. The following are the available wishes: %s' % [method for method in dir(request) if '_' not in method] else: return 'This is just a GET method' else: return "You are using POST" When I run this, this follows: C:\Python27\python.exe E:/Arindam/Projects/Flask_Practice/first.py * Restarting with stat * Debugger is active! * Debugger PIN: 581-155-269 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) Now lets try some calls. I am using the browser. http://127.0.0.1:5000/method This is just a GET method http://127.0.0.1:5000/method/NotCorrect This wish is not available. The following are the available wishes: ['application', 'args', 'authorization', 'blueprint', 'charset', 'close', 'cookies', 'data', 'date', 'endpoint', 'environ', 'files', 'form', 'headers', 'host', 'json', 'method', 'mimetype', 'module', 'path', 'pragma', 'range', 'referrer', 'scheme', 'shallow', 'stream', 'url', 'values'] http://127.0.0.1:5000/method/environ {'wsgi.multiprocess': False, 'HTTP_COOKIE': 'csrftoken=YFKYYZl3DtqEJJBwUlap28bLG1T4Cyuq', 'SERVER_SOFTWARE': 'Werkzeug/0.12.2', 'SCRIPT_NAME': '', 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/method/environ', 'SERVER_PROTOCOL': 'HTTP/1.1', 'QUERY_STRING': '', 'werkzeug.server.shutdown': , 'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36', 'HTTP_CONNECTION': 'keep-alive', 'SERVER_NAME': '127.0.0.1', 'REMOTE_PORT': 49569, 'wsgi.url_scheme': 'http', 'SERVER_PORT': '5000', 'werkzeug.request': , 'wsgi.input': , 'HTTP_HOST': '127.0.0.1:5000', 'wsgi.multithread': False, 'HTTP_UPGRADE_INSECURE_REQUESTS': '1', 'HTTP_ACCEPT': "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", 'wsgi.version': (1, 0), 'wsgi.run_once': False, 'wsgi.errors': ", mode 'w' at 0x0000000002042150>", 'REMOTE_ADDR': '127.0.0.1', 'HTTP_ACCEPT_LANGUAGE': 'en-US,en;q=0.8', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate, sdch, br'}
Another one that offers some customization and is easy to use (no install, signup) is https://beeceptor.com . You create a endpoint, makes a initial request to it and can tweak the responses.
I am using this REST API all the time: https://restful-api.dev It stores the created objects indefinitely. Also, the schema is quite flexible, you can pass any JSON data. I am a Front-End developer and is very useful when I need to create some sample data. This is the only one I could find that does it for free without any registration or tokens.
Just set one up yourself. Copy this snippet to your webserver. echo "<pre>"; print_r($_POST); echo "</pre>"; Just post what you want to that page. Done.