James Cathcart
James Cathcart

Reputation: 13

net/http connection refused over LAN

I have a simple Go REST API using just the net/http package from go (no frameworks as this is just a R&D tool). There is a docker-compose.yml that will bring up a mongo database if you wish to run the code: https://github.com/Workout-Widget/imu-rest-go/tree/1/connection-refused

The there is a basic dummy client, mock-rest-client.py, as well (a python script sending dummy values for test purposes). The client just sends this dummy data in a loop. Client repo: https://github.com/Workout-Widget/imu-sense-client

When these are run on the same machine (i.e. localhost/127.0.0.1) it works fine.

Tried disabling CORS with an adaptation of this tutorial, but it did not improve the situation: https://flaviocopes.com/golang-enable-cors/

I am not sure what the problem is but if I change the client to a LAN REST Server IP, the connection is refused. Any suggestions would be appreciated. Please, let me know if more clarity is needed.

The go handler code

package main

import (
    "context"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
    "log"
    "net/http"
    "time"
    "workoutwidget.fit/sensehatrest/controller"
    "workoutwidget.fit/sensehatrest/service"
)


func corsHandler(h http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        enableCors(&w)
        h(w, r)
    }
}

func enableCors(w *http.ResponseWriter) {

    (*w).Header().Set("Access-Control-Allow-Origin", "*")
    (*w).Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
    (*w).Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")

}

func main() {

    server := http.Server{
        Addr: "127.0.0.1:8080",
    }

    log.Println("Sense HAT REST API loading...")
    log.Println("Creating the database connection")
    // TODO insert mongo client here

    log.Println("Establishing database connection")
    client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017/test"))
    if err != nil {
        log.Fatalf("Could not connect to database! %s\n", err.Error())
    }
    log.Println("Getting context")
    ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)

    log.Println("Connecting to the database")
    err = client.Connect(ctx)

    log.Println("Instantiating Motion Controller")
    motionController := controller.MotionController{
        MotionRepo: &service.MotionService{
            Client: client,
        },
    }

    log.Println("Instantiating the Info Controller")
    infoController := controller.InfoController{}

    log.Println("Assigning handler functions...")
    http.HandleFunc("/motion/", corsHandler(motionController.HandleMotionRequest))
    http.HandleFunc("/experiment/", corsHandler(motionController.HandleExperimentRequest))
    http.HandleFunc("/info/", corsHandler(infoController.HandleInfoRequests))

    log.Println("Starting server...")
    err = server.ListenAndServe()
    if err != nil {
        panic(err)
    }
}

Client code:

import requests
import json
import time

rest_endpoint = "http://127.0.0.1:8080/motion/"
experiment_id = "NA"
sensorType = "NA"
inputDeviceId = "NA"
sensor_location = "NA"
exercise = "NA"
subject = "NA"

def make_post_call():
    data = {
        'xRoll': 0.1,
        'yPitch': 0.2,
        'zYaw': 0.3,
        'experimentId': experiment_id,
        'type': sensorType,
        'sensorLocation': sensor_location,
        'subject': subject,
        'isRaw': False,
        'timestamp': round(time.time() * 1000),
        'deviceId': inputDeviceId
    }
    requests.post(rest_endpoint, json=data)

while (True):
    make_post_call()
    time.sleep(.3)
    enter code here

Upvotes: 0

Views: 792

Answers (1)

Steven Masley
Steven Masley

Reputation: 697

Your webserver is being served on the address 127.0.0.1:8080. This only accepts connections from localhost. You need to change the listen address to :8080 or 0.0.0.0:8080

 server := http.Server{
        Addr: ":8080",
    }

Some more clarification

Setting the server listen address to 127.0.0.1:<port> is binding it your local network interface. This network interface is local to your machine.

Setting the address to 0.0.0.0:<port> binds the server to listen on all available network interfaces.

So you can actually decide which network interface to allow traffic from.

Upvotes: 1

Related Questions