How to configure and run a fastcgi application using Lighthttpd - c++

i've installed Lighthttpd for windows and i'd created a simple program in c++ which uses fastcgi libraries. i'll post the code here...
#include "fcgi_stdio.h"
#include <stdlib.h>
int count;
void initialize(void)
{
count=0;
}
void main(void)
{
initialize();
while (FCGI_Accept() >= 0) {
printf("Content-type: text/html\r\n"
"\r\n"
"<title>FastCGI Hello! (C, fcgi_stdio library)</title>"
"<h1>FastCGI Hello! (C, fcgi_stdio library)</h1>"
"Request number %d running on host <i>%s</i>\n",
++count, getenv("SERVER_HOSTNAME"));
}
}
I've spawned the fastcgi application in lighthttpd using the below configuration in lightttpd-inc.conf
fastcgi.server = ( ".exe" =>
( "" =>
(
"bin-path" => "D:\tinycgi.exe",
"port" => 8080,
"min-procs" => 1,
"max-procs" => 1
)
)
)
while sending a request using the browser the server is responding with this message in the console
2009-02-18 16:08:34: (mod_fastcgi.c.2494) unexpected end-of-file (perhaps the fa
stcgi process died): pid: 0 socket: tcp:localhost:8080
2009-02-18 16:08:34: (mod_fastcgi.c.3325) response not received, request sent: 1
024 on socket: tcp:localhost:8080 for /new/tinycgi.exe , closing connection
I think the fastcgi application is not spawned correctly.
Thank you,
Varun

First of all, main should return an int (not void).
The problem is most likely that you didn't call FCGX_Init() and didn't initialize the request (with FCGX_InitRequest()) either.
If you want to check if the application is spawned correctly, you should write to a log file, if lighttpd doesn't start the application, the log file won't be created.

Related

Golang Paho MQTT over Websocket

Hey I was trying to connect to AWS IoT Core via Golang Paho MQTT client. I tried the normal MQTT connection which was working without problems. Next I wanted to try the connection via MQTT over Websocket but could not find anything relating that in the Paho.Mqtt docs. How do I make the Websocket connection? I could post my code from my normal MQTT connection if necessary.
Edit, here is my code:
package main
import (
"crypto/tls"
"fmt"
"time"
MQTT "github.com/eclipse/paho.mqtt.golang"
)
type Message struct {
message string
}
/*var f MQTT.MessageHandler = func(client MQTT.Client, msg MQTT.Message) {
fmt.Printf("TOPIC: %s\n", msg.Topic())
fmt.Printf("MSG: %s\n", msg.Payload())
}*/
func main() {
cer, err := tls.LoadX509KeyPair("cd5a04e9fd9a094326c9ee0cdc1e1f7b2e3510a9e106968683d333a2a4344ca7-certificate.pem.crt",
"./cd5a04e9fd9a094326c9ee0cdc1e1f7b2e3510a9e106968683d333a2a4344ca7-private.pem.key")
check(err)
cid := "ClientID"
// AutoReconnect option is true by default
// CleanSession option is true by default
// KeepAlive option is 30 seconds by default
connOpts := MQTT.NewClientOptions() // This line is different, we use the constructor function instead of creating the instance ourselves.
connOpts.SetClientID(cid)
connOpts.SetMaxReconnectInterval(1 * time.Second)
connOpts.SetTLSConfig(&tls.Config{Certificates: []tls.Certificate{cer}})
host := "a2to6mbspmaw82-ats.iot.eu-west-1.amazonaws.com"
port := 443
brokerURL := fmt.Sprintf("wss://%s:%d", host, port)
connOpts.AddBroker(brokerURL)
mqttClient := MQTT.NewClient(connOpts)
if token := mqttClient.Connect(); token.Wait() && token.Error() != nil {
panic(token.Error())
}
var message = "message from lap"
for message != "bye" {
token := mqttClient.Publish("some_topic", 0, false, message)
token.Wait()
message = "bye"
}
}
func check(err error) {
if err != nil {
panic(err)
}
}
From the Eclipse Paho GoLang page
The type of connection required is specified by the scheme of the
connection URL set in the ClientOptions struct, for example:
tcp://mqtt.eclipseprojects.io:1883 - connect to mqtt.eclipseprojects.io on port 1883 using plain TCP
ws://mqtt.eclipseprojects.io:1883 - connect to mqtt.eclipseprojects.io on port 1883 using WebSockets
tls://mqtt.eclipseprojects.io:8883 - connect to mqtt.eclipseprojects.io on port 8883 using TLS (ssl:// and tcps:// are
synonyms for tls://)
The second entry in the list suggests you just pas in the URL with the right schema ( ws:// or probably wss://)

Communication between Flask and ESP8266 via SocketIO (Updated 2x)

I have a small web app for which the back-end is a Flask+SocketIO server. I would like to get some data from an ESP8266 into my app. The most simple way to achieve this I could think of was to have the micro controller connected directly to the back-end.
I am using the timum-viw library with this example code to implement the client on the micro controller.
The problem is that on trying to run the example I get
(12765) accepted ('192.168.0.11', 59848)
192.168.0.11 - - [06/Jul/2020 18:15:25] "GET /socket.io/?transport=websocket HTTP/1.1" 400 122 0.000265
192.168.0.11 - - [06/Jul/2020 18:15:31] code 400, message Bad request syntax ('This is a webSocket client!')
192.168.0.11 - - [06/Jul/2020 18:15:31] "This is a webSocket client!" 400 -
in the terminal window of the dev server. (The IP belongs to the ESP8266.)
I have the same experience with the arduinoWebSockets library and the WebSocketClientSocketIO example.
Can you help me figure out what the problem is?
Update
Everything is hosted locally at this point. I am running the flask dev server with python3 flask_main.py, eventlet is installed.
The minimal code that manifests the problem:
Arduino:
#include <SocketIoClient.h>
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <Hash.h>
#define USE_SERIAL Serial
#define SSID_primary "**********"
#define WIFI_PWD_primary "**********"
#define SERVER_IP "192.168.0.7"
#define SERVER_PORT 5005
ESP8266WiFiMulti wifiMulti;
SocketIoClient socketIOClient;
void setup() {
//// set up serial communication
USE_SERIAL.begin(115200);
USE_SERIAL.setDebugOutput(true);
for(uint8_t t = 4; t > 0; t--) {
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
USE_SERIAL.flush();
delay(1000);
}
//// connect to some access point
wifiMulti.addAP(SSID_primary, WIFI_PWD_primary);
while(wifiMulti.run() != WL_CONNECTED) {
delay(500);
USE_SERIAL.print("Looking for WiFi ");
}
USE_SERIAL.printf("Connected to %s\n", WiFi.SSID().c_str());
USE_SERIAL.printf("My local IP address is %s\n", WiFi.localIP().toString().c_str());
//// set up socket communication
socketIOClient.begin(SERVER_IP, SERVER_PORT);
}
void loop() {
socketIOClient.emit("message", "\"hi there :)\"");
socketIOClient.loop();
delay(1000);
}
Flask minimal code:
from flask import Flask, render_template, request
from flask_socketio import SocketIO
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
#socketio.on('message')
def handle_message_event(msg):
print('received msg from {} : {}'.format(request.remote_addr, str(msg)))
if __name__ == '__main__':
socketio.run(app, host="0.0.0.0", port=5005, debug=True)
The code below is for debugging only. I do not wish to use them in any form later.
Weirdly enough the Arduino code works fine with a node.js server:
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(5005);
io.attach(http, {
pingInterval: 10000,
pingTimeout: 5000,
cookie: false
});
io.on('connection', function (socket) {
console.log('user connected');
socket.on('disconnect', function () {
console.log('user disconnected');
});
socket.on('message', function (msg) {
console.log("message: "+msg);
});
timeout();
});
http.listen();
Could there be something wrong with my Flask? It responds to connections from this:
from socketIO_client import SocketIO, LoggingNamespace
socketIO = SocketIO('localhost', 5005, LoggingNamespace)
while True:
_ = raw_input("> ")
socketIO.emit('message', "hello 2")
But the node server does not!
Update 2
So I went ahead and looked at the communication with wire shark:
Python client & Flask server (works)
The payload of frame 27:
Hypertext Transfer Protocol
GET /socket.io/?EIO=3&transport=websocket&sid=8f47e9a521404b66b23cd985cdee049d HTTP/1.1\r\n
Upgrade: websocket\r\n
Host: localhost:5005\r\n
Origin: http://localhost:5005\r\n
Sec-WebSocket-Key: TQ589ew7EgwDILWb50Eu9Q==\r\n
Sec-WebSocket-Version: 13\r\n
Connection: upgrade\r\n
Connection: keep-alive\r\n
Accept-Encoding: gzip, deflate\r\n
Accept: */*\r\n
User-Agent: python-requests/2.18.4\r\n
\r\n
[Full request URI: http://localhost:5005/socket.io/?EIO=3&transport=websocket&sid=8f47e9a521404b66b23cd985cdee049d]
[HTTP request 1/1]
[Response in frame: 29]
Doing the same with the arduino & flask (does not work)
The payload of frame 34:
Hypertext Transfer Protocol
GET /socket.io/?transport=websocket HTTP/1.1\r\n
Host: 192.168.0.7:5005\r\n
Connection: Upgrade\r\n
Upgrade: websocket\r\n
Sec-WebSocket-Version: 13\r\n
Sec-WebSocket-Key: D9+/7YOHoA8lW7a/0V8vsA==\r\n
Sec-WebSocket-Protocol: arduino\r\n
Origin: file://\r\n
User-Agent: arduino-WebSocket-Client\r\n
\r\n
[Full request URI: http://192.168.0.7:5005/socket.io/?transport=websocket]
[HTTP request 1/1]
[Response in frame: 36]
So it turns out that Flask freaks out about the
Origin: file://\r\n
part because it thinks it is CORS. This is why this answer actually works, however I think it is the wrong fix. Removing this extra header entry is the right way to go about this. This is most simply done by editing this line to match this:
_client.extraHeaders = WEBSOCKETS_STRING("");
in your local library.
There goes hours of research :D

reactivemongo play 2.3 0.11.7 to 0.11.11 upgrade raises ExceptionInInitializerError

[I am re-editing this question to reflect on my last tests]
I am trying to upgrade my akka / play 2.3 application from
"org.reactivemongo" %% "play2-reactivemongo" % "0.11.7.play23"
to
"org.reactivemongo" %% "play2-reactivemongo" % "0.11.11-play23"
Compilation goes fine but at run-time I get the following error:
[ERROR] -- NettyTransport(akka://reactivemongo)
failed to bind to /127.0.0.1:2552, shutting down Netty transport
...
Caused by: org.jboss.netty.channel.ChannelException: Failed to bind to: /127.0.0.1:2552
The Akka part of application.conf reads as follows:
akka {
loggers = ["akka.event.slf4j.Slf4jLogger"]
loglevel = "DEBUG"
actor {
provider = "akka.remote.RemoteActorRefProvider"
mailbox {
requirements {
"akka.dispatch.BoundedMessageQueueSemantics" = bounded-mailbox
}
}
}
remote {
enabled-transports = ["akka.remote.netty.tcp"]
netty.tcp {
hostname = "127.0.0.1"
port = 2552
}
}
}
The exception is raised when trying to instantiate the reactivemongo driver
val driver = new reactivemongo.api.MongoDriver()
This suggests that the mongodriver is using Akka under the hood and is binding to the same address that my main application. And indeed, if I edit my application.conf and change the akka.remote.netty.tcp.port from 2552 to 2553, I get the following exception:
[ERROR] -- NettyTransport(akka://reactivemongo)
failed to bind to /127.0.0.1:2553, shutting down Netty transport
In the previous versions of reactivemongo, by default, instantiating the driver was starting a new actor system so maybe version 0.11.11 tries to reuse the existing system?
I have tried to modify the akka port used by the driver as follows:
val customConf = ConfigFactory.parseString("""
akka {
remote {
netty.tcp.port = 4711
}
}
""")
val typesafeConfig: com.typesafe.config.Config = ConfigFactory.load(customConf)
val driver = new reactivemongo.api.MongoDriver(Some(typesafeConfig))
But this does not work, the new port is not taken into account and I keep getting the same error:
[ERROR] -- NettyTransport(akka://reactivemongo)
failed to bind to /127.0.0.1:2552, shutting down Netty transport
Actually, ReactiveMongo loads its configuration from the key 'mongo-async-driver'.
So, Adding the following permits to configure ReactiveMongo underlying akka system:
val customConf = ConfigFactory.parseString("""
mongo-async-driver {
akka {
loglevel = WARNING
remote {
enabled-transports = ["akka.remote.netty.tcp"]
netty.tcp {
hostname = "127.0.0.1"
port = 4711
}
}
}
}
""")

Embedded Jetty not serving empty files

Setup: I have set up embedded jetty (v9.1) to serve static files with the setDirectoriesListed(true) and the code I am using is below:
// Create a basic Jetty server object that will listen on port 8080. Note that if you set this to port 0
// then a randomly available port will be assigned that you can either look in the logs for the port,
// or programmatically obtain it for use in test cases.
Server server = new Server(9090);
// Create the ResourceHandler. It is the object that will actually handle the request for a given file. It is
// a Jetty Handler object so it is suitable for chaining with other handlers as you will see in other examples.
ResourceHandler resource_handler = new ResourceHandler();
// Configure the ResourceHandler. Setting the resource base indicates where the files should be served out of.
// In this example it is the current directory but it can be configured to anything that the jvm has access to.
resource_handler.setDirectoriesListed(true);
resource_handler.setWelcomeFiles(new String[]{ "index.html" });
resource_handler.setResourceBase(".");
// Add the ResourceHandler to the server.
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { resource_handler, new DefaultHandler() });
server.setHandler(handlers);
// Start things up! By using the server.join() the server thread will join with the current thread.
// See "http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join()" for more details.
server.start();
server.join();
This code is originally from here.
When I navigate to the address http://localhost:9090/, I see the files listed in the directory and I am able to click and open individual text files.
Problem: For some inexplicable reason, only when I click on a file of 0 bytes (aka it's an empty file, but still shown in the browser), the connection tries to load but eventually times out (30 seconds) and I get a response in safari saying the "server unexpectedly dropped the connection." In addition, when I make a HttpURLConnection to the 0 byte file, I get a content length returned of -1; This of course is only for empty files.
Expected Behavior as seen in standalone Jetty: When I use standalone jetty and serve the same files, I am able to "open" the empty file which just returns a blank page in a web browser. When using the HttpURLConnection, I get a content length of 0.
While this seems like a "pointless" task, one server is programmatically syncing with the embedded jetty server (so I want those empty files to sync). I imagine it has something to do with the resource handler seeing 0 bytes as it serves the static content, but I'm not too sure how to get the same behavior of the standalone jetty server as right now, it errors when trying to pull the empty files.
Thanks!
Your code works, as-is, at least on Jetty 9.2.7.v20140116
Full example I used:
package jetty;
import java.io.File;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
public class SimpleResources
{
public static void main(String[] args)
{
Server server = new Server(9090);
String resourceBase = System.getProperty("resourceBase", ".");
System.err.printf("Resource Base is: %s%n", new File(resourceBase).getAbsolutePath());
ResourceHandler resource_handler = new ResourceHandler();
resource_handler.setDirectoriesListed(true);
resource_handler.setWelcomeFiles(new String[] { "index.html" });
resource_handler.setResourceBase(resourceBase);
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { resource_handler, new DefaultHandler() });
server.setHandler(handlers);
try
{
server.start();
server.join();
}
catch (Throwable t)
{
t.printStackTrace(System.err);
}
}
}
I ran it pointing the -DresourceBase system property to a directory that has the following ...
$ ls -la
total 8
drwxrwxr-x. 2 joakim joakim 4096 Jan 20 11:53 .
drwxrwxr-x. 3 joakim joakim 4096 Jan 20 11:53 ..
-rw-rw-r--. 1 joakim joakim 0 Jan 20 11:53 foo.txt
And once running the console shows ...
2015-01-20 11:55:07.788:INFO::main: Logging initialized #68ms
Resource Base is: /home/joakim/code/Jetty/empties
2015-01-20 11:55:07.837:INFO:oejs.Server:main: jetty-9.2.7.v20150116
2015-01-20 11:55:07.860:INFO:oejs.ServerConnector:main: Started ServerConnector#5461eda{HTTP/1.1}{0.0.0.0:9090}
2015-01-20 11:55:07.861:INFO:oejs.Server:main: Started #144ms
With a test request like such ...
$ curl --dump-header - http://localhost:9090/foo.txt
HTTP/1.1 200 OK
Date: Tue, 20 Jan 2015 18:55:39 GMT
Content-Type: text/plain
Content-Length: 0
Server: Jetty(9.2.7.v20150116)
Update:
Works as-is with no modifications on the following versions of jetty as well (didn't do an exhaustive test of versions, just a few older ones as well)
9.2.6.v20141205 - Identical Results
9.2.4.v20141103 - Identical Results
9.2.1.v20140609 - Identical Results
9.1.5.v20140505 - No Date in response headers, rest is the same (yes, it also sends Content-Length: 0)

Interaction between C++ and Rails applications

I have two applications: c++ service and a RoR web server (they are both running at same VPS)
I need to "send" some variables (and then do something with them) from each other. For exaple, i'm looking for something like this:
// my C++ sample
void SendMessage(string message) {
SendTo("127.0.0.1", message);
}
void GetMessage(string message) {
if (message == "stop")
SendMessage("success");
}
# Ruby sample
# application_controller.rb
def stop
#m = Messager.new
#m.send("stop")
end
I have never used it before, and i even don't know which technology should i search and learn.
Ok, i have found the solution. Its TCP sockets:
Ruby TCP server, to send messages:
require 'socket'
server = TCPServer.open(2000)
loop {
Thread.start(server.accept) do |client|
client.puts(Time.now.ctime)
client.puts "Closing the connection. Bye!"
client.close
end
}
Ruby client, to accept messages:
require 'socket'
host = 'localhost'
port = 2001 # it should be running server, or it will be connection error
s = TCPSocket.open(host, port)
while line = s.gets
puts line.chop
end
s.close
Now you should write TCP-server+client in another application. But you have got the idea.