11
$\begingroup$

I learned some codes to make a mini HTTP server in MMA way here.

server=SocketListen[8000,Function[{assoc},Block[{client=assoc["SourceSocket"]},
Block[{html,expr},
expr=First@StringCases[assoc["Data"],RegularExpression["GET /\\?expr=([^ ]+)"]->"$1"];
html=ToString@InputForm@ToExpression@URLDecode@expr;
WriteString[client,"HTTP/1.1 200 OK\r\nDate: "<>DateString[]<>"\r\nContent-Type: text/html\r\nContent-Length: "<>
ToString@StringLength@html<>"\n\n"<>html];
Close[client]]]]]

do not forget to close it when finished.

DeleteObject[server]
Close[server["Socket"]]

by the upper codes, we could pass exprs to MMA and get results in TEXTs way, I want to know how to show the Plots or Graphics with these codes in web browsers like Chrome? I wonder that, MMA could be used as web server, there should be some frameworks to help this becoming true, like Express upon node.js. is this worth to do sth? enter image description here

enter image description here

$\endgroup$
3
  • 1
    $\begingroup$ Perhaps ExportString[expr,"PNG"] and changing the response content-type to image/png might work. $\endgroup$
    – Carl Lange
    Commented Jan 18, 2019 at 18:18
  • 1
    $\begingroup$ Export string to HTMLFragment can help on both TEXT or PLOTs if set Content-Type value text/html $\endgroup$
    – Jerry
    Commented Jan 19, 2019 at 2:44
  • 2
    $\begingroup$ !!!WARNING: Injection risk comes true if exposed in network. Similarly, I remembered Exit[] executed when WloframAlpha firstly lanched as public knowledge engine. $\endgroup$
    – Jerry
    Commented Jan 19, 2019 at 2:48

2 Answers 2

8
$\begingroup$

You can get it to respond with images by doing the following:

server = SocketListen[8000, 
  Function[{assoc}, 
   Block[{client = assoc["SourceSocket"]}, 
    Block[{html, expr}, 
     expr = First@
       StringCases[assoc["Data"], 
        RegularExpression["GET /\\?expr=([^ ]+)"] -> "$1"];
     response = ExportString[ToExpression@URLDecode@expr, "PNG"];
     WriteString[client, 
      "HTTP/1.1 200 OK\r\nDate: " <> DateString[] <> 
       "\r\nContent-Type: image/png\r\nContent-Length: " <> 
       ToString@StringLength@response <> "\n\n" <> response];
     Close[client]]]]]

I've made 2 changes - first is to change the response Content-Type to image/png. Otherwise the browser doesn't know the response is an image.

Next I used ExportString[..., "PNG] to get MMA to respond with the string representation of an image, which, when coupled with the Content-Type change, will render correctly in a browser, as below.

working for images

To your broader question - in my opinion, to make this a real-live web server is a ton of work and probably not worth it when CloudDeploy and family exist.

$\endgroup$
3
  • $\begingroup$ Thanks! It's helpful to build a math webservice at least, while CloudDeploy depends on the Clould service. $\endgroup$
    – Jerry
    Commented Jan 18, 2019 at 18:35
  • $\begingroup$ I agree and I definitely think it would be cool! Be aware that it probably doesn't comply with your license if you open it up to the web at large. My license doesn't allow "Any type of remote access" to my subscription which you could probably put this under if you were a legal type :) $\endgroup$
    – Carl Lange
    Commented Jan 18, 2019 at 18:41
  • $\begingroup$ Surely, professional license is necessary to be applied, if worth to make the best use of the functions although it's expensive.:) $\endgroup$
    – Jerry
    Commented Jan 19, 2019 at 0:32
9
$\begingroup$

Very often SVG makes sense, it will scale well with magnification. This idea does not deserve a separate answer so additionally I rewrote the code in a more idiomatic style:

server = SocketListen[8000
, Function[{assoc}
  , Module[
      { client = assoc["SourceSocket"], inputString, response}

    , inputString = ImportString[assoc["Data"], "HTTPRequest"] @ "Query" // Lookup["expr"]

    ; response = GenerateHTTPResponse @ ExportForm[
        ToExpression[inputString], "SVG"
      ]

    ; WriteString[client, ExportString[response, "HTTPResponse"]]

    ; Close @ client
    ]
  ]      
]

enter image description here

(* DeleteObject[server]
   Close[server["Socket"]]
*)
$\endgroup$
4
  • $\begingroup$ Ah, I knew you or b3m2a1 would show up with a better answer! $\endgroup$
    – Carl Lange
    Commented Jan 19, 2019 at 0:41
  • $\begingroup$ Thanks! awesome! $\endgroup$
    – Jerry
    Commented Jan 19, 2019 at 0:44
  • $\begingroup$ Unfortunately this cool piece of code do work that well in Wolfram Engine 12 (Debian 9). It raise errors about zmq and recursion limit exceeded. Could you confirm this issue? thanks $\endgroup$
    – Fortsaint
    Commented May 30, 2019 at 15:05
  • $\begingroup$ @Fortsaint I didn't have time to play with WE yet, and I work on Windows, sorry. $\endgroup$
    – Kuba
    Commented May 31, 2019 at 16:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.