changeset 48:aabc1dd92639

Implemented close() and recv() methods on ServerSocket.
author Atul Varma <varmaa@toolness.com>
date Wed, 24 Jun 2009 15:58:54 -0700
parents e46bf8ff5dc5
children 45fd970860f2
files server_socket.cpp tcb.js
diffstat 2 files changed, 90 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/server_socket.cpp	Wed Jun 24 15:32:58 2009 -0700
+++ b/server_socket.cpp	Wed Jun 24 15:58:54 2009 -0700
@@ -59,9 +59,11 @@
 static void finalize(JSContext *cx, JSObject *obj)
 {
   PRFileDesc *fd = (PRFileDesc *) JS_GetPrivate(cx, obj);
-  // Just in case, ensure we don't have a dangling pointer.
-  JS_SetPrivate(cx, obj, NULL);
-  PR_Close(fd);
+  if (fd != NULL) {
+    // Just in case, ensure we don't have a dangling pointer.
+    JS_SetPrivate(cx, obj, NULL);
+    PR_Close(fd);
+  }
 }
 
 JSExtendedClass sServerSocket_JSClass = {
@@ -119,7 +121,55 @@
 static JSBool recv(JSContext *cx, JSObject *obj, uintN argc,
                    jsval *argv, jsval *rval)
 {
-  
+  PRInt32 length;
+
+  if (!JS_ConvertArguments(cx, argc, argv, "i", &length))
+    return JS_FALSE;
+
+  PRFileDesc *fd;
+  if (!getSocket(cx, obj, &fd))
+    return JS_FALSE;
+
+  char buffer[length];
+  PRInt32 recvd = PR_Recv(fd, buffer, length, 0, PR_INTERVAL_NO_TIMEOUT);
+
+  if (recvd == -1) {
+    JS_ReportError(cx, "Receive failed.");
+    return JS_FALSE;
+  }
+
+  if (recvd == 0) {
+    *rval = JSVAL_NULL;
+    return JS_TRUE;
+  }
+
+  JSString *string = JS_NewStringCopyN(cx, buffer, length);
+  if (string == NULL) {
+    JS_ReportOutOfMemory(cx);
+    return JS_FALSE;
+  }
+
+  *rval = STRING_TO_JSVAL(string);
+  return JS_TRUE;
+}
+
+static JSBool close(JSContext *cx, JSObject *obj, uintN argc,
+                    jsval *argv, jsval *rval)
+{
+  PRFileDesc *fd;
+  if (!getSocket(cx, obj, &fd))
+    return JS_FALSE;
+
+  PRStatus result = PR_Close(fd);
+  if (result != PR_SUCCESS) {
+    JS_ReportError(cx, "Close failed.");
+    return JS_FALSE;
+  }
+
+  JS_SetPrivate(cx, obj, NULL);
+
+  *rval = JSVAL_VOID;
+  return JS_TRUE;
 }
 
 static JSBool listen(JSContext *cx, JSObject *obj, uintN argc,
@@ -212,6 +262,7 @@
   JS_FS("accept",        accept,      0, 0, 0),
   JS_FS("send",          send,        1, 0, 0),
   JS_FS("recv",          recv,        1, 0, 0),
+  JS_FS("close",         close,       0, 0, 0),
   JS_FS_END
 };
 
--- a/tcb.js	Wed Jun 24 15:32:58 2009 -0700
+++ b/tcb.js	Wed Jun 24 15:58:54 2009 -0700
@@ -243,15 +243,40 @@
 socket.bind("127.0.0.1", 8080);
 socket.listen();
 
-var conn = socket.accept();
+var NEWLINE = "\r\n";
+var DOUBLE_NEWLINE = NEWLINE + NEWLINE;
+
+function getHeaders(conn) {
+  var headers = "";
+  while (1) {
+    var character = conn.recv(1);
+    if (character == null)
+      return null;
+    headers += character;
+    if (headers.indexOf(DOUBLE_NEWLINE) != -1)
+      return headers;
+  }
+}
+
+while (1) {
+  var conn = socket.accept();
 
-if (conn) {
-  var toSend = "hello there.";
-  var headerLines = ["HTTP/1.0 200 OK",
-                     "Content-Type: text/plain",
-                     "Content-Length: " + toSend.length];
-  var headers = headerLines.join("\r\n");
-  conn.send(headers);
-  conn.send("\r\n");
-  conn.send(toSend);
+  if (conn) {
+    var requestHeaders = getHeaders(conn);
+    if (requestHeaders == null)
+      continue;
+    //print("headers: " + uneval(requestHeaders));
+    var toSend = "hello there.";
+    var headerLines = ["HTTP/1.0 200 OK",
+                       "Content-Type: text/plain",
+                       "Connection: close",
+                       "Content-Length: " + toSend.length];
+    var headers = headerLines.join("\r\n");
+    var response = headers + DOUBLE_NEWLINE + toSend;
+    //print("response: " + uneval(response));
+    conn.send(response);
+    conn.close();
+    //print("response sent.");
+  } else
+    throw new Error("Unexpected: conn is " + conn);
 }