network.request( )

Description:

Makes an asynchronous HTTP or HTTPS request to a URL.

Syntax:

network.request( url, method, listener [, params] )

Example:
The following sample code contacts Google's encrypted search over SSL, and prints the response (in this case, the HTML source of the home page) to the Corona terminal:
local function networkListener( event )
        if ( event.isError ) then
                print( "Network error!")
        else
                print ( "RESPONSE: " .. event.response )
        end
end
 
-- Access Google over SSL:
network.request( "https://encrypted.google.com", "GET", networkListener )
The following code demonstrates a sending data via HTTP post.
local function networkListener( event )
        if ( event.isError ) then
                print( "Network error!")
        else
                print ( "RESPONSE: " .. event.response )
        end
end
 
postData = "color=red&size=small"
 
local params = {}
params.body = postData
 
network.request( "http://127.0.0.1/formhandler.php", "POST", networkListener, params)
The following code demonstrates how to attach custom HTTP headers and custom body message to a request. Note: Custom HTTP headers are functional in build 277 and later. Subscribers can download the latest daily build from the daily builds page.
headers = {}
 
headers["Content-Type"] = "application/json"
headers["Accept-Language"] = "en-US"
 
body = "This is an example request body."
 
local params = {}
params.headers = headers
params.body = body
 
network.request( "https://192.168.0.1/getData.php", "POST", networkListener,  params)
Parameters:

url
String: The HTTP request URL.

method
String: The HTTP method; valid values are "GET" (the default) or "POST".

listener
Function: The listener function invoked when the HTTP operation has completed. It is passed an event object that contains the following properties:

  • event.response
    A string containing the response from the server.
  • event.isError
    A boolean value: true in the case of a network error, false otherwise. As of build 2012.744, "event.isError" only returns true if we failed to connect to the server or upon response timeout
  • event.status
    A number value: The HTTP status code. (Only available starting with build 2012.744)

Note: The time-out for a network request is 30 seconds.

params
Table: An optional table that specifies custom HTTP headers or body to include in the request. To specify custom headers, attach a headers table that specifies header values with string keys. To specify a custom body message, attach a body property to this table whose string value is the HTTP body.

  • params.headers
    A table specifying header values with string keys.
  • params.body
  • A string containing the HTTP body.

Returns:

Nothing.

Remarks:

Android:
Async HTTP POST not working. [case 4459] - Fixed in daily build 505

Windows Simulator:
Async HTTP requests fail if the response header contains a "Connection: close". [case 4774] - Fixed in daily build 505

Sample Programs Using This API
/Networking/AsynchHTTP

Supported on operating systems and platforms for build numbers shown:
  • Mac OS X:
    Build 2011.268
  • Windows:
    Build 2011.484
  • iOS:
    Build 2011.268
  • Android:
    Build 2011.336

Replies

Matthew Pringle
User offline. Last seen 51 weeks 2 days ago. Offline
Joined: 23 Feb 2010

This creates a tcp server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
local function createTCPServer( port )
        
        -- Create Socket
        local tcpServerSocket , err = socket.tcp()
        local backlog = 5
        
        -- Check Socket
        if tcpServerSocket == nil then 
                return nil , err
        end
        
        -- Allow Address Reuse
        tcpServerSocket:setoption( "reuseaddr" , true )
        
        -- Bind Socket
        local res, err = tcpServerSocket:bind( "*" , port )
        if res == nil then
                return nil , err
        end
        
        -- Check Connection
        res , err = tcpServerSocket:listen( backlog )
        if res == nil then 
                return nil , err
        end
        
        -- Return Server
        return tcpServerSocket
        
end

This is the actual server, which needs to be in an enter frame loop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
local function runTCPServer()
 
        -- Set Timeout
        tcpServer:settimeout( 0 )
                
        -- Set Client
        local tcpClient , _ = tcpServer:accept()
 
        -- Get Message
        if tcpClient ~= nil then
 
                local tcpClientMessage , _ = tcpClient:receive('*l')
 
                if ( tcpClientMessage ~= nil ) then
                                
                        -- Get Message
                        local myMessage =  tcpClientMessage
 
                        -- Send a Response
                        tcpClient:send( "HELLO".."\n")
                                                                                                        
                end
 
                -- Close Client Connection
                if tcpClient ~= nil then
                                
                        tcpClient:close()
                        
                end
                
        else
                -- Error
 
        end
end

And you need to start the server with a port

1
2
tcpServer , _ = createTCPServer( "8080" )
Runtime:addEventListener( "enterFrame" , runTCPServer )

The _ where there should be a variable shows where there should be a variable to catch an error but you can leave the _ as lua will ignore whats passed back.

1
2
-- Note this!!!
tcpServer:settimeout( 0 )

The value in the timeout is 0 so its none blocking but from experience you need something like 0.001 for slower networks. Anything above 0 makes Corona wait in milliseconds so be careful with that.

This will make Corona into a http server which sends HELLO to whatever connects to it.

Matthew Pringle
User offline. Last seen 51 weeks 2 days ago. Offline
Joined: 23 Feb 2010

I forgot to mention you cant used reserved ports like port 80, so instead use 8080 and do something like http://192.168.0.1:8080 from the new network api.

You need to know in advance the http server ip address. I am thinking I could easily write an php based auto pairing server for 2 devices on the same network.

trollapps
User offline. Last seen 9 years 7 weeks ago. Offline
Joined: 25 Jan 2011

I'm attempting to manually set a header using params.headers but I'm unable to set any type of header without the Simulator crashing with a "33232 Abort trap" error. Does anyone have a quick example of setting a header?

Thanks

EDIT: I solved my problem, I read in the API that if Cookies weren't able to be set, then header variables had to be passed. I was able to get away with just doing this:

1
2
3
4
5
6
7
        local params = {}
        params["name"] = reader_SID
        params["domain"] = ".google.com"
        params["path"] = "/"
        params["expires"] = "1600000000"
        
        network.request( "http://www.google.com/reader/api/0/subscription/list", "GET", readerShowFeeds, params)

stuville
User offline. Last seen 6 years 19 weeks ago. Offline
Joined: 11 Sep 2010

If you are a Corona subscriber you should have access to the nightly beta builds. Headers work in build 298 as I tested it with a SOAP request and it works beautifully.

Tom
User offline. Last seen 4 years 6 weeks ago. Offline
Joined: 13 Jul 2010

Notice: Please limit comments on this page to corrections to the API information.

Submit any questions to the Forum and report bugs at bugs@anscamobile.com or use the "Report a Bug" link when you are logged into your account.

Thanks.

andyg
User offline. Last seen 8 years 49 weeks ago. Offline
Joined: 13 Apr 2011

@stuville can you post a SOAP example here or in the forums?

stuville
User offline. Last seen 6 years 19 weeks ago. Offline
Joined: 11 Sep 2010

Andy,

Sure! I will work up some example code and put it on Code Exchange this week.

Stu

andyg
User offline. Last seen 8 years 49 weeks ago. Offline
Joined: 13 Apr 2011

Hey @stuville, sorry to ping you. Did you post to the Code Exchange? I can't find any examples yet.

-Andy

sreekanth.goli
User offline. Last seen 8 years 17 weeks ago. Offline
Joined: 15 Sep 2011

Andy/Stuville,

Can you please post SOAP example?

Thanks
Sree

andyg
User offline. Last seen 8 years 49 weeks ago. Offline
Joined: 13 Apr 2011

Hi Sree,

I don't have any yet. Hopefully soon. If you find one please let us know!

-Andy

dgaedcke
User offline. Last seen 4 years 18 weeks ago. Offline
Joined: 17 Apr 2010

Ansca, would you document how to set timeout for the request?? MathewP above has shown how to set timeout on the specific socket, but httpRequest doesn't return a handle to the socket so it seems that won't work.

Has anyone found a way to control the timeout?

Thx--D

Joshua Quick
User offline. Last seen 2 years 13 weeks ago. Offline
Staff
Joined: 31 Jan 2011

dgaedcke,

You can't set the timeout for our network.request() or network.download() functions. Mathew is showing you how to set up a timeout for Lua sockets, which is a different networking API. The important difference is that Lua sockets are blocking and Corona's network.request() is non-blocking.

dgaedcke
User offline. Last seen 4 years 18 weeks ago. Offline
Joined: 17 Apr 2010

Can you at least tell us what the timeout is, or how/where it is set?? Is it OS specific? If I don't know how long to wait, how can I implement a check to know that my REST call never returned???

Joshua Quick
User offline. Last seen 2 years 13 weeks ago. Offline
Staff
Joined: 31 Jan 2011

network.request() has a 30 second request timeout on all platforms AFTER the TCP connection has been made. I believe the connection timeouts are inconsistent between platforms (we would have to do some digging on our part to figure it out), but I do know that the Corona Simulator for windows connection timeout is 1 minute.

That said, the network.request() listener will be invoked once the timeout has occurred, in which case the listener will receive an error. You can also receive error more quickly than that due to firewalls or lack of Internet connection on the device.

dgaedcke
User offline. Last seen 4 years 18 weeks ago. Offline
Joined: 17 Apr 2010

Thanks Josh.....that helps. And just FYI, I believe the Corona simulator on OS X might be blocking during this call because my app hangs for 30 seconds if I reload when my web-server is offline. Oh, that's probably because I was testing the call from main rather than from a EF handler after startup...user error ;-)

jasonshow
User offline. Last seen 8 years 8 weeks ago. Offline
Joined: 19 Jan 2011

when I wait for the response of network.request(), can I stop the network.request() listener ?

thanks.

Joshua Quick
User offline. Last seen 2 years 13 weeks ago. Offline
Staff
Joined: 31 Jan 2011

jasonshow,

No, you cannot disable the network request's listener. There is also no way to "abort" the network request. However, you can easily set up a flag in your Lua code that can be used within your listener function to avoid your normal handling.

sithu1986
User offline. Last seen 7 years 25 weeks ago. Offline
Joined: 3 Aug 2010

I want to use HTTP methods like PUT and DELETE. Is it possible some how? Thanks.

Joshua Quick
User offline. Last seen 2 years 13 weeks ago. Offline
Staff
Joined: 31 Jan 2011

sithu1986,

We haven't tested it with PUT or DELETE before, so you have to assume it won't. I'm quite sure neither one of these commands will work on Android. These commands should work on Windows. I don't know what will happen on OS X and iOS.

sithu1986
User offline. Last seen 7 years 25 weeks ago. Offline
Joined: 3 Aug 2010

I tested with DELETE and seems like it's working. But PUT doesn't work. :(

Joshua Quick
User offline. Last seen 2 years 13 weeks ago. Offline
Staff
Joined: 31 Jan 2011

Which platform did you test this on? OS X? iOS? Android?

sithu1986
User offline. Last seen 7 years 25 weeks ago. Offline
Joined: 3 Aug 2010

OSX Corona simulator. Haven't testing on devices, iOS, Android. Thanks.

Joshua Quick
User offline. Last seen 2 years 13 weeks ago. Offline
Staff
Joined: 31 Jan 2011

Officially, we only support "GET" and "POST" as documented on this page. That's just how it works for the time being.

Ideally, we should support any command/verb string that you give us and just put it into the HTTP request packet as is. I can write this up as a feature request for you, but it'll be low priority.

In the meantime, you can work-around this issue by using Lua sockets instead, with the one disadvantage being that Lua sockets are blocking (not async).

w2md
User offline. Last seen 6 years 48 weeks ago. Offline
Joined: 18 Oct 2010

Hey, Joshua.

"No, you cannot disable the network request's listener. There is also no way to "abort" the network request. However, you can easily set up a flag in your Lua code that can be used within your listener function to avoid your normal handling."

How would I set up a "flag" for this inside my project?

Thanks!

Joshua Quick
User offline. Last seen 2 years 13 weeks ago. Offline
Staff
Joined: 31 Jan 2011

Just set up a global boolean flag to ignore network request events like this...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
local m_isListening = true
local function networkListener( event )
   if (m_isListening) then
      if (event.isError) then
         print("Network Error!")
      else
         print("Response = " .. event.response)
      end
   else
      print("Response ignored."
   end
end
network.request( "www.mysite.com", "GET", networkListener )
 
-- Ignore response by setting this to false.
m_isListening = false

bob.dickinson
User offline. Last seen 6 years 50 weeks ago. Offline
Joined: 15 Dec 2011

GET and POST, really? So no talking to REST APIs that require PUT and DELETE? I'm working on getting Corona to talk to Amazon S3 right now, and this is a pretty big problem if it doesn't actually work.

And yes, I get that I can use the blocking APIs, but I think everybody knows that's a non-starter for a decent quality mobile app (which is why the async APIs exist, I assume).

Being able to do a PUT and DELETE is pretty important. Getting access to the response code and headers would also be really nice (getting the S3 "GET" to work was a lot more work than it should have been because all I had was "isError").

I'm going to cross my fingers and hope that PUT and DELETE actually work, even though they aren't "supported", but it would really be nice to prioritize having decent async HTTP support that allowed for easy integration with web services/APIs (by this I mean GET/PUT/DELETE and response code/headers).

bob.dickinson
User offline. Last seen 6 years 50 weeks ago. Offline
Joined: 15 Dec 2011

When attempting a simple "PUT" using network.request on Android I got a callback event that said:

"HTTP method 'PUT' not supported"

Joshua Quick
User offline. Last seen 2 years 13 weeks ago. Offline
Staff
Joined: 31 Jan 2011

Hello Bob,

As noted up above, I did write up a feature request to support any verb/method in a HTTP request and not just "GET" or "POST". I've just increased the priority of this feature request today, along with accessing the response headers which is another popular request. I will try to push for this change for the next upcoming release of the Corona SDK.

In the meantime, the only work-around is to use Lua sockets, which unfortunately is a blocking operation.

bob.dickinson
User offline. Last seen 6 years 50 weeks ago. Offline
Joined: 15 Dec 2011

@Joshua - that would be awesome. I've been knee-deep in both the sockets and async for a few days now (finally have my app talking to Amazon S3).

I have a few other things I'd like to share regarding how I think async should work. What's the best way to get that to you (or whoever the right person is)? Thanks.

sithu1986
User offline. Last seen 7 years 25 weeks ago. Offline
Joined: 3 Aug 2010

I'm testing with CloudyRec.com as the backend for my Corona game. It needs PUT to update data through its API.

Looking forward to have this feature so that we can create online mobile games easily.

Thanks,

Joshua Quick
User offline. Last seen 2 years 13 weeks ago. Offline
Staff
Joined: 31 Jan 2011

Bob,

Please feel free to submit feature requests via the link below...
http://developer.anscamobile.com/forms/support

We welcome everyone's ideas. Naturally, the more requests we receive for a particular feature, the higher the priority it becomes for us to implement it.

personalnadir
User offline. Last seen 6 years 45 weeks ago. Offline
Joined: 24 Nov 2010

Hey guys,

Is there any documentation on the upper limits of data that can be submitted over the POST command?

I'm looking to sync potentially a couple of mega bytes to the server, am I going to need to be smart about this?

Thanks,

Joshua Quick
User offline. Last seen 2 years 13 weeks ago. Offline
Staff
Joined: 31 Jan 2011

personalnadir,

To be honest, I'm not sure what the maximum is. I suspect that it is limited by memory since all of the data you want to send via a single HTTP request must be applied to the body parameter. If what you are sending is several SEVERAL megabytes, then this would be a pretty bad memory hit. Plus it would be a performance hit copying you data to the body parameters, which in turn will need to be copied over to the TCP packet internally.

The most efficient way to handle this would be to break it up into several network requests and stream the data from file via the Lua io functions. At least that's how I would do it. This all depends on what your options are for the server of course. Anyways, that's my 2 cents.

bob.dickinson
User offline. Last seen 6 years 50 weeks ago. Offline
Joined: 15 Dec 2011

@personalnadir and @Joshua,

I did ask for this also in my feature request / bug report. My suggestion was to allow for the specification of a "bodyFile" in params that pointed to a filePath or fileName/baseDir. Or alternatively, supporting a file handle in the existing "body" param (closing it when finished) - the file handle way is how LuaSocket does it via the file source, which I kind of like, giving you the freedom to open the file yourself or even provide a different file-like object to supply the data.

You can certainly upload from a file with LuaSocket, which works fine as long as you don't need https. There is an async http module shared in codeplex that I have used in my S3 library with some success:

http://developer.anscamobile.com/code/cross-platform-asynchronous-http-request

So that will get you a *sort of* async solution using LuaSocket.

It would be nice to see Ansca support upload (request body) from a file. It seems like a fairly easy fix and would make life a lot easier.

personalnadir
User offline. Last seen 6 years 45 weeks ago. Offline
Joined: 24 Nov 2010

Thanks guys for the feedback. At the moment I'm only developing on the iPad 2 over WiFi only, so I'm not too worried about performance, as long as the data it submitted.

I'll bear it in mind though.

Tom
User offline. Last seen 4 years 6 weeks ago. Offline
Joined: 13 Jul 2010

The comment section for this API has been closed. Please continue the discussion on the Corona forums.
http://developer.anscamobile.com/forum/2012/04/03/networkrequest