forked from apache/thrift
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
THRIFT-893 JavaScript Tutorial: dynamic part
git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1030018 13f79535-47bb-0310-9956-ffa450edef68
- Loading branch information
1 parent
a8b52c7
commit e5e50de
Showing
3 changed files
with
381 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
<!-- | ||
Licensed to the Apache Software Foundation (ASF) under one | ||
or more contributor license agreements. See the NOTICE file | ||
distributed with this work for additional information | ||
regarding copyright ownership. The ASF licenses this file | ||
to you under the Apache License, Version 2.0 (the | ||
"License"); you may not use this file except in compliance | ||
with the License. You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, | ||
software distributed under the License is distributed on an | ||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, either express or implied. See the License for the | ||
specific language governing permissions and limitations | ||
under the License. | ||
--> | ||
<project name="tutorial" default="test" basedir="."> | ||
|
||
<description>Thrift JavaScript Tutorial</description> | ||
|
||
<property name="src" location="src" /> | ||
<property name="javasrc" location="../java/src" /> | ||
<property name="gen" location="../gen-java" /> | ||
<property name="build" location="build" /> | ||
|
||
<!-- the root directory, where you unpack thrift distibution (e.g. thrift-0.x.x.tar.gz) --> | ||
<property name="thrift.dir" location="../../" /> | ||
<property name="thrift.java.dir" location="${thrift.dir}/lib/java" /> | ||
|
||
<path id="libs.classpath"> | ||
<pathelement path="${thrift.java.dir}/libthrift.jar" /> | ||
<fileset dir="${thrift.java.dir}/build/ivy/lib"> | ||
<include name="*.jar" /> | ||
</fileset> | ||
</path> | ||
<path id="build.classpath"> | ||
<path refid="libs.classpath" /> | ||
<pathelement path="${gen}" /> | ||
<pathelement path="${build}" /> | ||
</path> | ||
|
||
<target name="init"> | ||
<tstamp /> | ||
<mkdir dir="${build}"/> | ||
</target> | ||
|
||
<target name="compile" depends="init"> | ||
<javac srcdir="${gen}" destdir="${build}" classpathref="libs.classpath" /> | ||
<javac srcdir="${javasrc}" destdir="${build}" classpathref="build.classpath"> | ||
<exclude name="JavaClient.java"/> | ||
<exclude name="JavaServer.java"/> | ||
<include name="CalculatorHandler.java"/> | ||
</javac> | ||
<javac srcdir="${src}" destdir="${build}" classpathref="build.classpath"> | ||
<compilerarg value="-Xlint:all"/> | ||
</javac> | ||
</target> | ||
|
||
<target name="tutorial" depends="compile"> | ||
<jar jarfile="tutorial-js.jar" basedir="${build}"/> | ||
</target> | ||
|
||
<target name="test" description="run the test server" depends="tutorial"> | ||
<java classname="Httpd" fork="true" | ||
classpathref="build.classpath" failonerror="true"> | ||
<arg value="../../" /> | ||
</java> | ||
</target> | ||
|
||
<target name="clean"> | ||
<delete dir="${build}" /> | ||
<delete file="tutorial-js.jar" /> | ||
</target> | ||
|
||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,299 @@ | ||
/* | ||
* ==================================================================== | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you under the Apache License, Version 2.0 (the | ||
* "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
* ==================================================================== | ||
* | ||
* This software consists of voluntary contributions made by many | ||
* individuals on behalf of the Apache Software Foundation. For more | ||
* information on the Apache Software Foundation, please see | ||
* <http://www.apache.org/>. | ||
* | ||
*/ | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.io.InterruptedIOException; | ||
import java.io.OutputStream; | ||
import java.io.OutputStreamWriter; | ||
import java.net.ServerSocket; | ||
import java.net.Socket; | ||
import java.net.URLDecoder; | ||
import java.util.Locale; | ||
|
||
import org.apache.http.ConnectionClosedException; | ||
import org.apache.http.HttpEntity; | ||
import org.apache.http.HttpEntityEnclosingRequest; | ||
import org.apache.http.HttpException; | ||
import org.apache.http.HttpRequest; | ||
import org.apache.http.HttpResponse; | ||
import org.apache.http.HttpServerConnection; | ||
import org.apache.http.HttpStatus; | ||
import org.apache.http.MethodNotSupportedException; | ||
import org.apache.http.entity.ContentProducer; | ||
import org.apache.http.entity.EntityTemplate; | ||
import org.apache.http.entity.FileEntity; | ||
import org.apache.http.impl.DefaultHttpResponseFactory; | ||
import org.apache.http.impl.DefaultHttpServerConnection; | ||
import org.apache.http.impl.NoConnectionReuseStrategy; | ||
import org.apache.http.params.BasicHttpParams; | ||
import org.apache.http.params.CoreConnectionPNames; | ||
import org.apache.http.params.CoreProtocolPNames; | ||
import org.apache.http.params.HttpParams; | ||
import org.apache.http.protocol.BasicHttpContext; | ||
import org.apache.http.protocol.BasicHttpProcessor; | ||
import org.apache.http.protocol.HttpContext; | ||
import org.apache.http.protocol.HttpProcessor; | ||
import org.apache.http.protocol.HttpRequestHandler; | ||
import org.apache.http.protocol.HttpRequestHandlerRegistry; | ||
import org.apache.http.protocol.HttpService; | ||
import org.apache.http.util.EntityUtils; | ||
import org.apache.thrift.TProcessor; | ||
import org.apache.thrift.protocol.TJSONProtocol; | ||
import org.apache.thrift.protocol.TProtocol; | ||
import org.apache.thrift.transport.TMemoryBuffer; | ||
|
||
// Generated code | ||
import tutorial.*; | ||
import shared.*; | ||
|
||
import java.util.HashMap; | ||
|
||
/** | ||
* Basic, yet fully functional and spec compliant, HTTP/1.1 file server. | ||
* <p> | ||
* Please note the purpose of this application is demonstrate the usage of | ||
* HttpCore APIs. It is NOT intended to demonstrate the most efficient way of | ||
* building an HTTP file server. | ||
* | ||
* | ||
*/ | ||
public class Httpd { | ||
|
||
public static void main(String[] args) throws Exception { | ||
if (args.length < 1) { | ||
System.err.println("Please specify document root directory"); | ||
System.exit(1); | ||
} | ||
Thread t = new RequestListenerThread(8088, args[0]); | ||
t.setDaemon(false); | ||
t.start(); | ||
} | ||
|
||
static class HttpFileHandler implements HttpRequestHandler { | ||
|
||
private final String docRoot; | ||
|
||
public HttpFileHandler(final String docRoot) { | ||
super(); | ||
this.docRoot = docRoot; | ||
} | ||
|
||
public void handle(final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException { | ||
|
||
String method = request.getRequestLine().getMethod().toUpperCase(Locale.ENGLISH); | ||
if (!method.equals("GET") && !method.equals("HEAD") && !method.equals("POST")) { | ||
throw new MethodNotSupportedException(method + " method not supported"); | ||
} | ||
String target = request.getRequestLine().getUri(); | ||
|
||
if (request instanceof HttpEntityEnclosingRequest && target.equals("/thrift/service/tutorial/")) { | ||
HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity(); | ||
byte[] entityContent = EntityUtils.toByteArray(entity); | ||
System.out.println("Incoming content: " + new String(entityContent)); | ||
|
||
final String output = this.thriftRequest(entityContent); | ||
|
||
System.out.println("Outgoing content: "+output); | ||
|
||
EntityTemplate body = new EntityTemplate(new ContentProducer() { | ||
|
||
public void writeTo(final OutputStream outstream) throws IOException { | ||
OutputStreamWriter writer = new OutputStreamWriter(outstream, "UTF-8"); | ||
writer.write(output); | ||
writer.flush(); | ||
} | ||
|
||
}); | ||
body.setContentType("text/html; charset=UTF-8"); | ||
response.setEntity(body); | ||
} else { | ||
final File file = new File(this.docRoot, URLDecoder.decode(target, "UTF-8")); | ||
if (!file.exists()) { | ||
|
||
response.setStatusCode(HttpStatus.SC_NOT_FOUND); | ||
EntityTemplate body = new EntityTemplate(new ContentProducer() { | ||
|
||
public void writeTo(final OutputStream outstream) throws IOException { | ||
OutputStreamWriter writer = new OutputStreamWriter(outstream, "UTF-8"); | ||
writer.write("<html><body><h1>"); | ||
writer.write("File "); | ||
writer.write(file.getPath()); | ||
writer.write(" not found"); | ||
writer.write("</h1></body></html>"); | ||
writer.flush(); | ||
} | ||
|
||
}); | ||
body.setContentType("text/html; charset=UTF-8"); | ||
response.setEntity(body); | ||
System.out.println("File " + file.getPath() + " not found"); | ||
|
||
} else if (!file.canRead() || file.isDirectory()) { | ||
|
||
response.setStatusCode(HttpStatus.SC_FORBIDDEN); | ||
EntityTemplate body = new EntityTemplate(new ContentProducer() { | ||
|
||
public void writeTo(final OutputStream outstream) throws IOException { | ||
OutputStreamWriter writer = new OutputStreamWriter(outstream, "UTF-8"); | ||
writer.write("<html><body><h1>"); | ||
writer.write("Access denied"); | ||
writer.write("</h1></body></html>"); | ||
writer.flush(); | ||
} | ||
|
||
}); | ||
body.setContentType("text/html; charset=UTF-8"); | ||
response.setEntity(body); | ||
System.out.println("Cannot read file " + file.getPath()); | ||
|
||
} else { | ||
|
||
response.setStatusCode(HttpStatus.SC_OK); | ||
FileEntity body = new FileEntity(file, "text/html"); | ||
response.setEntity(body); | ||
System.out.println("Serving file " + file.getPath()); | ||
|
||
} | ||
} | ||
} | ||
|
||
private String thriftRequest(byte[] input){ | ||
try{ | ||
|
||
//Input | ||
TMemoryBuffer inbuffer = new TMemoryBuffer(input.length); | ||
inbuffer.write(input); | ||
TProtocol inprotocol = new TJSONProtocol(inbuffer); | ||
|
||
//Output | ||
TMemoryBuffer outbuffer = new TMemoryBuffer(100); | ||
TProtocol outprotocol = new TJSONProtocol(outbuffer); | ||
|
||
TProcessor processor = new Calculator.Processor(new CalculatorHandler()); | ||
processor.process(inprotocol, outprotocol); | ||
|
||
byte[] output = new byte[outbuffer.length()]; | ||
outbuffer.readAll(output, 0, output.length); | ||
|
||
return new String(output,"UTF-8"); | ||
}catch(Throwable t){ | ||
return "Error:"+t.getMessage(); | ||
} | ||
|
||
|
||
} | ||
|
||
} | ||
|
||
static class RequestListenerThread extends Thread { | ||
|
||
private final ServerSocket serversocket; | ||
private final HttpParams params; | ||
private final HttpService httpService; | ||
|
||
public RequestListenerThread(int port, final String docroot) throws IOException { | ||
this.serversocket = new ServerSocket(port); | ||
this.params = new BasicHttpParams(); | ||
this.params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 1000).setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024) | ||
.setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false).setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true) | ||
.setParameter(CoreProtocolPNames.ORIGIN_SERVER, "HttpComponents/1.1"); | ||
|
||
// Set up the HTTP protocol processor | ||
HttpProcessor httpproc = new BasicHttpProcessor(); | ||
|
||
// Set up request handlers | ||
HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry(); | ||
reqistry.register("*", new HttpFileHandler(docroot)); | ||
|
||
// Set up the HTTP service | ||
this.httpService = new HttpService(httpproc, new NoConnectionReuseStrategy(), new DefaultHttpResponseFactory()); | ||
this.httpService.setParams(this.params); | ||
this.httpService.setHandlerResolver(reqistry); | ||
} | ||
|
||
public void run() { | ||
System.out.println("Listening on port " + this.serversocket.getLocalPort()); | ||
System.out.println("Point your browser to http://localhost:8088/tutorial/js/tutorial.html"); | ||
|
||
while (!Thread.interrupted()) { | ||
try { | ||
// Set up HTTP connection | ||
Socket socket = this.serversocket.accept(); | ||
DefaultHttpServerConnection conn = new DefaultHttpServerConnection(); | ||
System.out.println("Incoming connection from " + socket.getInetAddress()); | ||
conn.bind(socket, this.params); | ||
|
||
// Start worker thread | ||
Thread t = new WorkerThread(this.httpService, conn); | ||
t.setDaemon(true); | ||
t.start(); | ||
} catch (InterruptedIOException ex) { | ||
break; | ||
} catch (IOException e) { | ||
System.err.println("I/O error initialising connection thread: " + e.getMessage()); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
|
||
static class WorkerThread extends Thread { | ||
|
||
private final HttpService httpservice; | ||
private final HttpServerConnection conn; | ||
|
||
public WorkerThread(final HttpService httpservice, final HttpServerConnection conn) { | ||
super(); | ||
this.httpservice = httpservice; | ||
this.conn = conn; | ||
} | ||
|
||
public void run() { | ||
System.out.println("New connection thread"); | ||
HttpContext context = new BasicHttpContext(null); | ||
try { | ||
while (!Thread.interrupted() && this.conn.isOpen()) { | ||
this.httpservice.handleRequest(this.conn, context); | ||
} | ||
} catch (ConnectionClosedException ex) { | ||
System.err.println("Client closed connection"); | ||
} catch (IOException ex) { | ||
System.err.println("I/O error: " + ex.getMessage()); | ||
} catch (HttpException ex) { | ||
System.err.println("Unrecoverable HTTP protocol violation: " + ex.getMessage()); | ||
} finally { | ||
try { | ||
this.conn.shutdown(); | ||
} catch (IOException ignore) { | ||
} | ||
} | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters