This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Xavura's profile picture

The HTTP API should allow us to set headers.

Started by Xavura, 04 February 2013 - 09:36 PM
Xavura #1
Posted 04 February 2013 - 10:36 PM
I was going to do some stuff with the GitHub API but parts of their API require the use of headers (e.g. X-GitHub-Media-Type) so I'm unable to do what I wanted. :(/>

I don't see why we shouldn't be able to send headers.
1lann #2
Posted 05 February 2013 - 04:13 AM
Agreed, this would be nice. Although you could just have a php script on a server parse it for you.
Herû #3
Posted 05 February 2013 - 09:09 AM
It would be nice, but I are agree with 1lann, you could let a php script do it for you (you must make a small php script, but it's easy).
Xavura #4
Posted 05 February 2013 - 02:34 PM
That means that anyone who wants to do anything with HTTP headers needs to own a server.

That's absurd.
Amarite1 #5
Posted 05 February 2013 - 02:41 PM
You don't need to own a server, but you need some server on which to host your script. There are plenty of free hosts out there that you could use.
Xavura #6
Posted 05 February 2013 - 04:25 PM
I know you can get free servers, you're all missing the point.

It's still a terrible alternative to what would be a simple addition that makes a ton of sense.
Dlcruz129 #7
Posted 05 February 2013 - 05:12 PM
I know you can get free servers, you're all missing the point.

It's still a terrible alternative to what would be a simple addition that makes a ton of sense.

You're welcome to make your own mod if this one's not good enough for you.
raineth #8
Posted 10 February 2013 - 09:52 AM
You're welcome to make your own mod if this one's not good enough for you.
Is that attitude really productive here?

Anyway, HTTP headers are an important part of the protocol and exposing a method to set custom headers (which could just be another optional parameter to the existing functions) seems like a perfectly reasonable request.

I was going to do some stuff with the GitHub API but parts of their API require the use of headers (e.g. X-GitHub-Media-Type) so I'm unable to do what I wanted. :(/>
ComputerCraft doesn't fully sanitize the request URL, so it's possible to inject extra headers into the request that way (with the caveat that the request won't be 100% standard compliant – see the comments below).

Try this:
--- Wrapper around the HTTP API functions to inject HTTP headers.
-- Example usage:
--   headers = {
--     ["Cache-Control"] = "no-store",
--     ["X-Example"] = "true",
--     ["X-Magic"] = "plugh",
--   }
--   success = httpWithHeaders(http.get, "http://www.example.com", nil,
--                             headers)
--
-- @param method The underlying API function to call (e.g. http.get).
-- @param url The request URL.
-- @param post_data HTTP POST data or nil - exact behaviour is defined by
--   underlying function.
-- @param headers Table containing HTTP headers as "X-Header" = "value" pairs
--   or nil for unaltered behaviour.
-- @return The return value of the specified method.
function httpWithHeaders(method, url, post_data, headers)
  local t
  local requestheaders = ''

  t = type(method)
  if t ~= "function" and
      -- callable table
      not (t == "table" and (getmetatable(method) or {}).__call) then
    error("bad argument #1 to httpWithHeaders (function expected,  got " ..
          t .. ")")
  end

  if headers then
    t = type(headers)
    if t ~= "table" then
      error("bad argument #4 to httpWithHeaders (table or nil expected, " ..
            "got " ..  t .. ")")
    end

    -- Inject HTTP headers into the url.  The HTTP API does not allow characters
    -- after a \n in the url, so we can only use \r as the line terminator.
    -- This is technically a violation of the HTTP standard (which requires
    -- \r\n) but is accepted by most web servers.
    for header, value in pairs(headers) do
      requestheaders = requestheaders .. header .. ": " .. value .. "\r"
    end

    -- Only alter the URL if the table had something in it
    if requestheaders ~= '' then
      url = url .. " HTTP/1.1\r" .. requestheaders ..
        -- Catch the HTTP/1.1 from the original request because we already
        -- sent one (and are therefore in the header part of the request).
        "X-Real-HTTP-Version: "
    end
  end

  return method(url, post_data)
end
Eric #9
Posted 10 February 2013 - 11:23 AM
A related addition to the HTTP API would be to allow reading of response headers, most importantly status codes.

@raineth: Nice! (+1)
dissy #10
Posted 10 February 2013 - 01:15 PM
A related addition to the HTTP API would be to allow reading of response headers, most importantly status codes.

@raineth: Nice! (+1)

You can already read the status code returned from the server. When one of the two events http_success or http_failure comes in, there are three parameters returned from the pullEvent: the event string, the url called, and a handle
You can then call handle.getResponseCode() to get the actual numerical code from the server.

Of course if http_success was the event, odds are the status code is 200. But on a http_failure you can check this to see if it's a 4xx code and thus a hard error, or perhaps a 3xx code that can be dealt with.

There is an example here: http://computercraft.info/wiki/Http_success_%28event%29


As to sending headers to the server, when I asked for this feature a few months ago, it was explained to me by someone (I can't recall the name, sorry) that LuaJ does not have any facilities to send http headers, which would explain why it can't be added to computer craft.
theoriginalbit #11
Posted 10 February 2013 - 01:21 PM
A related addition to the HTTP API would be to allow reading of response headers, most importantly status codes.

@raineth: Nice! (+1)

You can already read the status code returned from the server. When one of the two events http_success or http_failure comes in, there are three parameters returned from the pullEvent: the event string, the url called, and a handle
You can then call handle.getResponseCode() to get the actual numerical code from the server.

Of course if http_success was the event, odds are the status code is 200. But on a http_failure you can check this to see if it's a 4xx code and thus a hard error, or perhaps a 3xx code that can be dealt with.

There is an example here: http://computercraft...ess_%28event%29


As to sending headers to the server, when I asked for this feature a few months ago, it was explained to me by someone (I can't recall the name, sorry) that LuaJ does not have any facilities to send http headers, which would explain why it can't be added to computer craft.
http_failure does not return a handle, so you cannot get the response code from it.

http://computercraft.info/wiki/Http_failure_%28event%29
Cloudy #12
Posted 10 February 2013 - 01:45 PM
Headers would be nice. I'll look into expanding functionality.
Elemecca #13
Posted 14 February 2013 - 12:26 AM
ComputerCraft doesn't fully sanitize the request URL, so it's possible to inject extra headers into the request that way (with the caveat that the request won't be 100% standard compliant – see the comments below).

The HTTP API does not allow characters after a \n in the url, so we can only use \r as the line terminator. This is technically a violation of the HTTP standard (which requires \r\n) but is accepted by most web servers.

Unfortunately GitHub uses nginx, which is not one of the servers that support bare CR line endings. If you make a request with CRs in the URL it gets very confused and resets the connection.

As to sending headers to the server, when I asked for this feature a few months ago, it was explained to me by someone (I can't recall the name, sorry) that LuaJ does not have any facilities to send http headers, which would explain why it can't be added to computer craft.

LuaJ shouldn't be especially involved. It doesn't have an HTTP library, so CC would have had to implement their own. There's nothing in the LuaJ extension facilities that would prevent the request function taking a table of headers. Maybe they got confused because the method on the URLConnection interface for setting headers is rather strangely named addRequestProperty.