From 29952d5b4f182026d86b578f8d3d9de92e6e9a59 Mon Sep 17 00:00:00 2001 From: SquidDev Date: Mon, 1 May 2017 17:28:20 +0100 Subject: [PATCH] Various extensions to the HTTP API - A response is returned on the event of a HTTP error (such as 404). - Responses include the response headers. --- .../computercraft/core/apis/HTTPAPI.java | 20 ++++++++--- .../computercraft/core/apis/HTTPRequest.java | 34 +++++++++++++++++-- .../assets/computercraft/lua/bios.lua | 4 +-- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/src/main/java/dan200/computercraft/core/apis/HTTPAPI.java b/src/main/java/dan200/computercraft/core/apis/HTTPAPI.java index cc31d8fe1..2aed3d0ba 100644 --- a/src/main/java/dan200/computercraft/core/apis/HTTPAPI.java +++ b/src/main/java/dan200/computercraft/core/apis/HTTPAPI.java @@ -52,12 +52,16 @@ public void advance( double _dt ) if( h.wasSuccessful() ) { // Queue the "http_success" event final BufferedReader contents = h.getContents(); - final int responseCode = h.getResponseCode(); - final Object result = wrapBufferedReader( contents, responseCode ); + final Object result = wrapBufferedReader( contents, h.getResponseCode(), h.getResponseHeaders() ); m_apiEnvironment.queueEvent( "http_success", new Object[] { url, result } ); } else { // Queue the "http_failure" event - m_apiEnvironment.queueEvent( "http_failure", new Object[] { url, "Could not connect" } ); + BufferedReader contents = h.getContents(); + Object result = null; + if( contents != null ) { + result = wrapBufferedReader( contents, h.getResponseCode(), h.getResponseHeaders() ); + } + m_apiEnvironment.queueEvent( "http_failure", new Object[]{ url, "Could not connect", result } ); } it.remove(); } @@ -65,7 +69,7 @@ public void advance( double _dt ) } } - private static ILuaObject wrapBufferedReader( final BufferedReader reader, final int responseCode ) + private static ILuaObject wrapBufferedReader( final BufferedReader reader, final int responseCode, final Map> responseHeaders ) { return new ILuaObject() { @Override @@ -75,7 +79,8 @@ public String[] getMethodNames() "readLine", "readAll", "close", - "getResponseCode" + "getResponseCode", + "getResponseHeaders", }; } @@ -131,6 +136,11 @@ public Object[] callMethod( ILuaContext context, int method, Object[] args ) thr // getResponseCode return new Object[] { responseCode }; } + case 4: + { + // getResponseHeaders + return new Object[] { responseHeaders }; + } default: { return null; diff --git a/src/main/java/dan200/computercraft/core/apis/HTTPRequest.java b/src/main/java/dan200/computercraft/core/apis/HTTPRequest.java index c0525504b..8b7a7a3e1 100644 --- a/src/main/java/dan200/computercraft/core/apis/HTTPRequest.java +++ b/src/main/java/dan200/computercraft/core/apis/HTTPRequest.java @@ -12,6 +12,8 @@ import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; +import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.regex.Pattern; @@ -130,7 +132,16 @@ public void run() } // Read response - InputStream is = connection.getInputStream(); + InputStream is; + int code = connection.getResponseCode(); + boolean responseSuccess; + if (code >= 200 && code < 400) { + is = connection.getInputStream(); + responseSuccess = true; + } else { + is = connection.getErrorStream(); + responseSuccess = false; + } InputStreamReader isr; try { @@ -192,9 +203,21 @@ public void run() { // We completed m_complete = true; - m_success = true; + m_success = responseSuccess; m_result = result.toString(); m_responseCode = connection.getResponseCode(); + + Map> headers = m_responseHeaders = new HashMap>(); + for (Map.Entry> header : connection.getHeaderFields().entrySet()) { + Map values = new HashMap(); + + int i = 0; + for (String value : header.getValue()) { + values.put(++i, value); + } + + headers.put(header.getKey(), values); + } } } @@ -241,6 +264,12 @@ public int getResponseCode() { } } + public Map> getResponseHeaders() { + synchronized (m_lock) { + return m_responseHeaders; + } + } + public boolean wasSuccessful() { synchronized(m_lock) { @@ -270,4 +299,5 @@ public BufferedReader getContents() private boolean m_success; private String m_result; private int m_responseCode; + private Map> m_responseHeaders; } diff --git a/src/main/resources/assets/computercraft/lua/bios.lua b/src/main/resources/assets/computercraft/lua/bios.lua index 7c4e44256..5b4a10f52 100644 --- a/src/main/resources/assets/computercraft/lua/bios.lua +++ b/src/main/resources/assets/computercraft/lua/bios.lua @@ -643,11 +643,11 @@ if http then local ok, err = nativeHTTPRequest( _url, _post, _headers ) if ok then while true do - local event, param1, param2 = os.pullEvent() + local event, param1, param2, param3 = os.pullEvent() if event == "http_success" and param1 == _url then return param2 elseif event == "http_failure" and param1 == _url then - return nil, param2 + return nil, param2, param3 end end end