Merge branch 'request-headers' of https://github.com/invliD/OpenComputers into master-MC1.7.10

This commit is contained in:
Florian Nücke 2015-12-27 14:52:34 +01:00
commit 7c2a0541e4
4 changed files with 20 additions and 7 deletions

View File

@ -892,6 +892,9 @@ opencomputers {
# the `request` method on internet card components becomes available. # the `request` method on internet card components becomes available.
enableHttp: true enableHttp: true
# Whether to allow adding custom headers to HTTP requests.
enableHttpHeaders: true
# Whether to allow TCP connections via internet cards. When enabled, # Whether to allow TCP connections via internet cards. When enabled,
# the `connect` method on internet card components becomes available. # the `connect` method on internet card components becomes available.
enableTcp: true enableTcp: true

View File

@ -6,9 +6,10 @@ local internet = {}
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
function internet.request(url, data) function internet.request(url, data, headers)
checkArg(1, url, "string") checkArg(1, url, "string")
checkArg(2, data, "string", "table", "nil") checkArg(2, data, "string", "table", "nil")
checkArg(3, headers, "table", "nil")
local inet = component.internet local inet = component.internet
if not inet then if not inet then
@ -25,7 +26,7 @@ function internet.request(url, data)
end end
end end
local request, reason = inet.request(url, post) local request, reason = inet.request(url, post, headers)
if not request then if not request then
error(reason, 2) error(reason, 2)
end end

View File

@ -273,6 +273,7 @@ class Settings(val config: Config) {
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
// internet // internet
val httpEnabled = config.getBoolean("internet.enableHttp") val httpEnabled = config.getBoolean("internet.enableHttp")
val httpHeadersEnabled = config.getBoolean("internet.enableHttpHeaders")
val tcpEnabled = config.getBoolean("internet.enableTcp") val tcpEnabled = config.getBoolean("internet.enableTcp")
val httpHostBlacklist = Array(config.getStringList("internet.blacklist").map(new Settings.AddressValidator(_)): _*) val httpHostBlacklist = Array(config.getStringList("internet.blacklist").map(new Settings.AddressValidator(_)): _*)
val httpHostWhitelist = Array(config.getStringList("internet.whitelist").map(new Settings.AddressValidator(_)): _*) val httpHostWhitelist = Array(config.getStringList("internet.whitelist").map(new Settings.AddressValidator(_)): _*)

View File

@ -16,6 +16,7 @@ import li.cil.oc.util.ThreadPoolFactory
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
import net.minecraft.server.MinecraftServer import net.minecraft.server.MinecraftServer
import scala.collection.convert.WrapAsScala._
import scala.collection.mutable import scala.collection.mutable
class InternetCard extends prefab.ManagedEnvironment { class InternetCard extends prefab.ManagedEnvironment {
@ -35,7 +36,7 @@ class InternetCard extends prefab.ManagedEnvironment {
@Callback(direct = true, doc = """function():boolean -- Returns whether HTTP requests can be made (config setting).""") @Callback(direct = true, doc = """function():boolean -- Returns whether HTTP requests can be made (config setting).""")
def isHttpEnabled(context: Context, args: Arguments): Array[AnyRef] = result(Settings.get.httpEnabled) def isHttpEnabled(context: Context, args: Arguments): Array[AnyRef] = result(Settings.get.httpEnabled)
@Callback(doc = """function(url:string[, postData:string]):userdata -- Starts an HTTP request. If this returns true, further results will be pushed using `http_response` signals.""") @Callback(doc = """function(url:string[, postData:string[, headers:table]]):userdata -- Starts an HTTP request. If this returns true, further results will be pushed using `http_response` signals.""")
def request(context: Context, args: Arguments): Array[AnyRef] = this.synchronized { def request(context: Context, args: Arguments): Array[AnyRef] = this.synchronized {
checkOwner(context) checkOwner(context)
val address = args.checkString(0) val address = args.checkString(0)
@ -46,7 +47,13 @@ class InternetCard extends prefab.ManagedEnvironment {
throw new IOException("too many open connections") throw new IOException("too many open connections")
} }
val post = if (args.isString(1)) Option(args.checkString(1)) else None val post = if (args.isString(1)) Option(args.checkString(1)) else None
val request = new InternetCard.HTTPRequest(this, checkAddress(address), post) val headers = if (args.isTable(2)) args.checkTable(2).collect {
case (key: String, value: AnyRef) => (key, value.toString)
}.toMap else Map.empty[String, String]
if (!Settings.get.httpHeadersEnabled && headers.size > 0) {
return result(Unit, "http request headers are unavailable")
}
val request = new InternetCard.HTTPRequest(this, checkAddress(address), post, headers)
connections += request connections += request
result(request) result(request)
} }
@ -276,10 +283,10 @@ object InternetCard {
} }
class HTTPRequest extends AbstractValue with Closable { class HTTPRequest extends AbstractValue with Closable {
def this(owner: InternetCard, url: URL, post: Option[String]) { def this(owner: InternetCard, url: URL, post: Option[String], headers: Map[String, String]) {
this() this()
this.owner = Some(owner) this.owner = Some(owner)
this.stream = threadPool.submit(new RequestSender(url, post)) this.stream = threadPool.submit(new RequestSender(url, post, headers))
} }
private var owner: Option[InternetCard] = None private var owner: Option[InternetCard] = None
@ -378,13 +385,14 @@ object InternetCard {
} }
// This one doesn't (see comment in TCP socket), but I like to keep it consistent. // This one doesn't (see comment in TCP socket), but I like to keep it consistent.
private class RequestSender(val url: URL, val post: Option[String]) extends Callable[InputStream] { private class RequestSender(val url: URL, val post: Option[String], val headers: Map[String, String]) extends Callable[InputStream] {
override def call() = try { override def call() = try {
checkLists(InetAddress.getByName(url.getHost), url.getHost) checkLists(InetAddress.getByName(url.getHost), url.getHost)
val proxy = Option(MinecraftServer.getServer.getServerProxy).getOrElse(java.net.Proxy.NO_PROXY) val proxy = Option(MinecraftServer.getServer.getServerProxy).getOrElse(java.net.Proxy.NO_PROXY)
url.openConnection(proxy) match { url.openConnection(proxy) match {
case http: HttpURLConnection => try { case http: HttpURLConnection => try {
http.setDoInput(true) http.setDoInput(true)
headers.foreach(Function.tupled(http.setRequestProperty _))
if (post.isDefined) { if (post.isDefined) {
http.setRequestMethod("POST") http.setRequestMethod("POST")
http.setDoOutput(true) http.setDoOutput(true)