0

I'm trying to make a http get, using Lua Socket:

local client = socket.connect('warm-harbor-2019.herokuapp.com',80)
if client then
    client:send("GET /get_tweets HTTP/1.0\r\n\r\n")
      s, status, partial = client:receive(1024)
    end
end

I expect s to be a tweet, since the get that I'm making returns one. But I'm getting:

http/1.1 404 object not found
Matheus Lima
  • 2,103
  • 3
  • 31
  • 49

1 Answers1

5

Here is a runnable version of your code example (that exhibit the problem you described):

local socket = require "socket"
local client = socket.connect('warm-harbor-2019.herokuapp.com',80)
if client then
    client:send("GET /get_tweets HTTP/1.0\r\n\r\n")
    local s, status, partial = client:receive(1024)
    print(s)
end

If you read the error page returned, you can see that its title is Heroku | No such app.

The reason for that is that the Heroku router only works when a Host header is provided. The easiest way to do it is to use the actual HTTP module of LuaSocket instead of TCP directly:

local http = require "socket.http"
local s, status, headers = http.request("http://warm-harbor-2019.herokuapp.com/get_tweets")
print(s)

If you cannot use socket.http you can pass the Host header manually:

local socket = require "socket"
local client = socket.connect('warm-harbor-2019.herokuapp.com',80)
client:send("GET /get_tweets HTTP/1.0\r\nHost: warm-harbor-2019.herokuapp.com\r\n\r\n")
local s, status, partial = client:receive(1024)
print(s, status, partial)

With my version of LuaSocket, s will be nil, status will be "closed" and partial will contain the full HTTP response (with headers etc).

catwell
  • 6,770
  • 1
  • 23
  • 21
  • Looks solid, but my require 'socket.http' is not working, only require 'socket'. Do I need to add a file to the project? Right now, i just have one lua file. – Matheus Lima May 18 '14 at 19:49
  • 1
    This is probably because you use an old version of LuaSocket. If you require "socket" (without assigning it to a local variable) does `socket.http` exist? If so replace `http.request` by `socket.http.request`. – catwell May 18 '14 at 21:42
  • Ok, I'm using NCLua. I did what you told, in a separated file, and it worked fine. But for some reason 'socket' is working, but 'socket.http' is not. Is there a way to do it with 'socket' ? – Matheus Lima May 18 '14 at 22:22