Creating cookie in vertx - java

I want to create a simple cookie using vertx.
import io.vertx.core.AbstractVerticle;
import io.vertx.core.http.HttpHeaders;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.ext.web.Cookie;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import java.util.Date;
public class HttpVerticle extends AbstractVerticle {
#Override
public void start() throws Exception {
HttpServer server = vertx.createHttpServer();
Router router = Router.router(vertx);
router.route("/opt-out").handler(this::optOut);
System.out.println("Server started # 3000");
server.requestHandler(router::accept).listen(3000);
}
public void optOut(RoutingContext context) {
HttpServerRequest request = context.request();
HttpServerResponse response = context.response();
response.putHeader("content-type", "text-plain");
response.setChunked(true);
response.write("hellow world");
Cookie cookie = Cookie.cookie("foo", "bar");
context.addCookie(cookie);
response.end();
}
}
But when I check the browser, I see not cookies stamped by the name "foo", having value "bar". What am I doing wrong?
Also, how can I access all the cookies that is stamped?

This is how a cookie is set in Vertx.
#Override
public void start(Future<Void> future) {
Router router = Router.router(vertx);
router.route().handler(CookieHandler.create());
router.get("/set-cookie").handler(this::setCookieHandler);
}
public void setCookieHandler(RoutingContext context) {
String name = "foo";
String value = "bar";
long age = 158132000l; //5 years in seconds
Cookie cookie = Cookie.cookie(name,value);
String path = "/"; //give any suitable path
cookie.setPath(path);
cookie.setMaxAge(age); //if this is not there, then a session cookie is set
context.addCookie(cookie);
context.response().setChunked(true);
context.response().putHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
context.response().putHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET");
context.response().write("Cookie Stamped -> " + name + " : " +value);
context.response().end();
}
Thanks.

First, you need to add a CookieHandler in your Router.
This is the JavaDoc for addCookie method:
router.route().handler(CookieHandler.create());
/**
* Add a cookie. This will be sent back to the client in the response. The context must have first been
* to a {#link io.vertx.ext.web.handler.CookieHandler} for this to work.
*
* #param cookie the cookie
* #return a reference to this, so the API can be used
So, use the ".end()" method in response instead ".write()"
response.end("hellow world");

Related

Given a Ratpack RequestFixture test, how can I have the fixture invoke Request#beforeSend?

This question is in the context of a Ratpack RequestFixture Spock test, for a Ratpack chain authenticating with RatpackPac4j#requireAuth, and employing a workaround for the missing WWW-Authenticate header (as described in the answer to this question)
The problem I have is, I find that #beforeSend appears to be uncalled when the response is obtained from GroovyRequestFixture#handle (a wrapper for RequestFixture#handle). The work-around depends on this to work, so I can't test it. Is there a way to get #beforeSend called on the response represented by the HandlingResult returned?
For example, this test case fails with the assertion that the WWW-Authenticate header is present, even though the code this is adapted from inserts the header correctly when called in the actual application. The chain under test is testChain, skip to the end for the failing assertion:
package whatever
import com.google.inject.Module
import groovy.transform.Canonical
import groovy.transform.CompileDynamic
import groovy.transform.CompileStatic
import org.pac4j.core.profile.jwt.JwtClaims
import org.pac4j.http.client.direct.HeaderClient
import org.pac4j.jwt.config.encryption.EncryptionConfiguration
import org.pac4j.jwt.config.encryption.SecretEncryptionConfiguration
import org.pac4j.jwt.config.signature.SecretSignatureConfiguration
import org.pac4j.jwt.config.signature.SignatureConfiguration
import org.pac4j.jwt.credentials.authenticator.JwtAuthenticator
import org.pac4j.jwt.profile.JwtGenerator
import org.pac4j.jwt.profile.JwtProfile
import ratpack.groovy.handling.GroovyChainAction
import ratpack.groovy.test.handling.GroovyRequestFixture
import ratpack.guice.Guice
import ratpack.http.Response
import ratpack.http.Status
import ratpack.jackson.Jackson
import ratpack.pac4j.RatpackPac4j
import ratpack.registry.Registry
import ratpack.session.SessionModule
import ratpack.test.handling.HandlerExceptionNotThrownException
import ratpack.test.handling.HandlingResult
import spock.lang.Specification
#CompileStatic
class AuthenticatorTest extends Specification {
static byte[] salt = new byte[32] // dummy salt
static SignatureConfiguration signatureConfiguration = new SecretSignatureConfiguration(salt)
static EncryptionConfiguration encryptionConfiguration = new SecretEncryptionConfiguration(salt)
static JwtAuthenticator authenticator = new JwtAuthenticator(signatureConfiguration, encryptionConfiguration)
static JwtGenerator generator = new JwtGenerator(signatureConfiguration, encryptionConfiguration)
static HeaderClient headerClient = new HeaderClient("Authorization", "bearer ", authenticator)
/** A stripped down user class */
#Canonical
static class User {
final String id
}
/** A stripped down user registry class */
#Canonical
static class UserRegistry {
private final Map<String, String> users = [
'joebloggs': 'sekret'
]
User authenticate(String id, String password) {
if (password != null && users[id] == password)
return new User(id)
return null
}
}
/** Generates a JWT token for a given user
*
* #param userId - the name of the user
* #return A JWT token encoded as a string
*/
static String generateToken(String userId) {
JwtProfile profile = new JwtProfile()
profile.id = userId
profile.addAttribute(JwtClaims.ISSUED_AT, new Date())
String token = generator.generate(profile)
token
}
static void trapExceptions(HandlingResult result) {
try {
Throwable t = result.exception(Throwable)
throw t
}
catch (HandlerExceptionNotThrownException ignored) {
}
}
/** Composes a new registry binding the module class passed
* as per SO question https://stackoverflow.com/questions/50814817/how-do-i-mock-a-session-in-ratpack-with-requestfixture
*/
static Registry addModule(Registry registry, Class<? extends Module> module) {
Guice.registry { it.module(module) }.apply(registry)
}
GroovyChainAction testChain = new GroovyChainAction() {
#Override
#CompileDynamic
void execute() throws Exception {
register addModule(registry, SessionModule)
all RatpackPac4j.authenticator(headerClient)
all {
/*
* This is a workaround for an issue in RatpackPac4j v2.0.0, which doesn't
* add the WWW-Authenticate header by itself.
*
* See https://github.com/pac4j/ratpack-pac4j/issues/3
*
* This handler needs to be ahead of any potential causes of 401 statuses
*/
response.beforeSend { Response response ->
if (response.status.code == 401) {
response.headers.set('WWW-Authenticate', 'bearer realm="authenticated api"')
}
}
next()
}
post('login') { UserRegistry users ->
parse(Jackson.fromJson(Map)).then { Map data ->
// Validate the credentials
String id = data.user
String password = data.password
User user = users.authenticate(id, password)
if (user == null) {
clientError(401) // Bad authentication credentials
} else {
response.contentType('text/plain')
// Authenticates ok. Issue a JWT token to the client which embeds (signed, encrypted)
// certain standardised metadata of our choice that the JWT validation will use.
String token = generateToken(user.id)
render token
}
}
}
get('unprotected') {
render "hello"
}
// All subsequent paths require authentication
all RatpackPac4j.requireAuth(HeaderClient)
get('protected') {
render "hello"
}
notFound()
}
}
#CompileDynamic
def "should be denied protected path, unauthorised..."() {
given:
def result = GroovyRequestFixture.handle(testChain) {
uri 'protected'
method 'GET'
}
expect:
result.status == Status.of(401) // Unauthorized
// THIS FAILS BECAUSE Response#beforeSend WASN'T INVOKED BY GroovyRequestFixture
result.headers['WWW-Authenticate'] == 'bearer realm="authenticated api"'
// If the server threw, rethrow that
trapExceptions(result)
}
}
Best answer so far... or more strictly, a workaround to sidestep the limitations of RequestFixture, is: don't use RequestFixture. Use GroovyEmbeddedApp
(Credit to Dan Hyun on the Ratpack slack channel)
RequestFixture is only meant to check handler behavior, it doesn't do a lot of
things - it won't serialize responses. EmbeddedApp is probably the way to go
for most testing. You'd care more about overall interaction rather than how an
individual handler does a thing, unless it was a highly reused component or is
middleware that is used by other apps
An modified version of the example above follows, I've marked the modified sections in the comments:
package whatever
import com.google.inject.Module
import groovy.transform.Canonical
import groovy.transform.CompileDynamic
import groovy.transform.CompileStatic
import org.pac4j.core.profile.jwt.JwtClaims
import org.pac4j.http.client.direct.HeaderClient
import org.pac4j.jwt.config.encryption.EncryptionConfiguration
import org.pac4j.jwt.config.encryption.SecretEncryptionConfiguration
import org.pac4j.jwt.config.signature.SecretSignatureConfiguration
import org.pac4j.jwt.config.signature.SignatureConfiguration
import org.pac4j.jwt.credentials.authenticator.JwtAuthenticator
import org.pac4j.jwt.profile.JwtGenerator
import org.pac4j.jwt.profile.JwtProfile
import ratpack.groovy.test.embed.GroovyEmbeddedApp
import ratpack.guice.Guice
import ratpack.http.Response
import ratpack.http.Status
import ratpack.http.client.ReceivedResponse
import ratpack.jackson.Jackson
import ratpack.pac4j.RatpackPac4j
import ratpack.registry.Registry
import ratpack.session.SessionModule
import ratpack.test.handling.HandlerExceptionNotThrownException
import ratpack.test.handling.HandlingResult
import ratpack.test.http.TestHttpClient
import spock.lang.Specification
#CompileStatic
class TempTest extends Specification {
static byte[] salt = new byte[32] // dummy salt
static SignatureConfiguration signatureConfiguration = new SecretSignatureConfiguration(salt)
static EncryptionConfiguration encryptionConfiguration = new SecretEncryptionConfiguration(salt)
static JwtAuthenticator authenticator = new JwtAuthenticator(signatureConfiguration, encryptionConfiguration)
static JwtGenerator generator = new JwtGenerator(signatureConfiguration, encryptionConfiguration)
static HeaderClient headerClient = new HeaderClient("Authorization", "bearer ", authenticator)
/** A stripped down user class */
#Canonical
static class User {
final String id
}
/** A stripped down user registry class */
#Canonical
static class UserRegistry {
private final Map<String, String> users = [
'joebloggs': 'sekret'
]
User authenticate(String id, String password) {
if (password != null && users[id] == password)
return new User(id)
return null
}
}
/** Generates a JWT token for a given user
*
* #param userId - the name of the user
* #return A JWT token encoded as a string
*/
static String generateToken(String userId) {
JwtProfile profile = new JwtProfile()
profile.id = userId
profile.addAttribute(JwtClaims.ISSUED_AT, new Date())
String token = generator.generate(profile)
token
}
static void trapExceptions(HandlingResult result) {
try {
Throwable t = result.exception(Throwable)
throw t
}
catch (HandlerExceptionNotThrownException ignored) {
}
}
/** Composes a new registry binding the module class passed
* as per SO question https://stackoverflow.com/questions/50814817/how-do-i-mock-a-session-in-ratpack-with-requestfixture
*/
static Registry addModule(Registry registry, Class<? extends Module> module) {
Guice.registry { it.module(module) }.apply(registry)
}
/*** USE GroovyEmbeddedApp HERE INSTEAD OF GroovyResponseFixture ***/
GroovyEmbeddedApp testApp = GroovyEmbeddedApp.ratpack {
bindings {
module SessionModule
}
handlers {
all RatpackPac4j.authenticator(headerClient)
all {
/*
* This is a workaround for an issue in RatpackPac4j v2.0.0, which doesn't
* add the WWW-Authenticate header by itself.
*
* See https://github.com/pac4j/ratpack-pac4j/issues/3
*
* This handler needs to be ahead of any potential causes of 401 statuses
*/
response.beforeSend { Response response ->
if (response.status.code == 401) {
response.headers.set('WWW-Authenticate', 'bearer realm="authenticated api"')
}
}
next()
}
post('login') { UserRegistry users ->
parse(Jackson.fromJson(Map)).then { Map data ->
// Validate the credentials
String id = data.user
String password = data.password
User user = users.authenticate(id, password)
if (user == null) {
clientError(401) // Bad authentication credentials
} else {
response.contentType('text/plain')
// Authenticates ok. Issue a JWT token to the client which embeds (signed, encrypted)
// certain standardised metadata of our choice that the JWT validation will use.
String token = generateToken(user.id)
render token
}
}
}
get('unprotected') {
render "hello"
}
// All subsequent paths require authentication
all RatpackPac4j.requireAuth(HeaderClient)
get('protected') {
render "hello"
}
notFound()
}
}
/*** THIS NOW ALTERED TO USE testApp ***/
#CompileDynamic
def "should be denied protected path, unauthorised..."() {
given:
TestHttpClient client = testApp.httpClient
ReceivedResponse response = client.get('protected')
expect:
response.status == Status.of(401) // Unauthorized
response.headers['WWW-Authenticate'] == 'bearer realm="authenticated api"'
}
}

How to set the HTTP-Session-Timeout in Jetty 9 (embedded)?

I would like to use Jetty 9 (v9.2.12.v20150709) embedded for my test cases.
But I am unable to change the HTTP-Session-Timeout programmatically.
This call webapp.getSessionHandler().getSessionManager().setMaxInactiveInterval(timeoutInSeconds); doesn't seem to work.
Here is reduced code segement, which shows what I do:
import java.io.IOException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext;
#SuppressWarnings("javadoc")
public class EmbeddedJetty
{
#SuppressWarnings("serial")
public static class TimeoutServlet extends HttpServlet
{
#Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException
{
// return the value of the currently used HTTP-Session Timeout
response.setContentType("text/html");
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().println("<h1>Timeout: " + request.getSession()
.getMaxInactiveInterval() + "</h1>");
}
}
public static void main(String[] args) throws Exception
{
// the custom timeout, which I am trying to set
int timeoutInSeconds = 1234;
Server server = new Server(0);
WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/");
webapp.setResourceBase(System.getProperty("user.dir"));
// Can't set custom timeout. Following Statement doesn't work.
webapp.getSessionHandler().getSessionManager().setMaxInactiveInterval(
timeoutInSeconds);
server.setHandler(webapp);
webapp.addServlet(TimeoutServlet.class.getName(), "/*");
server.start();
// get current URL of the server
String url = server.getURI().toString();
System.out.println("\n URL: " + url);
// server.dumpStdErr();
// make a request to get the used timeout setting
HttpClient httpClient = new HttpClient();
httpClient.start();
ContentResponse response = httpClient.GET(url);
httpClient.stop();
String timeoutInfo = response.getContentAsString();
System.out.println(timeoutInfo);
// check if the custom timeout is used
if( timeoutInfo.contains(String.valueOf(timeoutInSeconds)) )
{
System.out.println("Custom Timeout is used.");
}
else
{
// Unfortunately, I get the default(?) everytime
System.out.println("Default Timeout? Custom Value is NOT used.");
}
System.out.println("Press Enter to exit ...");
System.in.read();
server.stop();
server.join();
}
}
I am using the WebAppContext-Style of setup, because this allowed me to get my ServletContextListeners to work by using WebAppContext.addEventListener(). Which I couldn't get to work by using a ServletHandler.
Also I am using the Version 9.2.12.v20150709 of Jetty, because it is Classpath-compatible with Selenium v2.5.2 (which supports Java 7 (project requirement)).
Have you any suggestions, what i am doing wrong?
Thank you for your time.
A WebAppContext has some defaults, which are loaded during server.start() (WebAppContext.startContext()).
These defaults contain also a DefaultWebDescriptor located in the jetty-webapp.jar under /org/eclipse/jetty/webapp/webdefault.xml. This Descriptor includes a session-config, which sets the timeout to the default of 30m (1800s).
To overwrite the defaults the call of setMaxInactiveInterval() must be done after the server is started:
server.start();
webapp.getSessionHandler().getSessionManager().setMaxInactiveInterval(timeoutInSeconds);
Or to avoid these defaults, it might be better to use a ServletContextHandler instead.

Grizzly Http Server - accepting only one connection at a time

I have a Grizzly Http Server with Async processing added. It is queuing my requests and processing only one request at a time, despite adding async support to it.
Path HttpHandler was bound to is: "/"
Port number: 7777
Behavior observed when I hit http://localhost:7777 from two browsers simultaneously is:
Second call waits till first one is completed. I want my second http call also to work simultaneously in tandom with first http call.
EDIT Github link of my project
Here are the classes
GrizzlyMain.java
package com.grizzly;
import java.io.IOException;
import java.net.URI;
import javax.ws.rs.core.UriBuilder;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.grizzly.http.server.NetworkListener;
import org.glassfish.grizzly.nio.transport.TCPNIOTransport;
import org.glassfish.grizzly.strategies.WorkerThreadIOStrategy;
import org.glassfish.grizzly.threadpool.ThreadPoolConfig;
import com.grizzly.http.IHttpHandler;
import com.grizzly.http.IHttpServerFactory;
public class GrizzlyMain {
private static HttpServer httpServer;
private static void startHttpServer(int port) throws IOException {
URI uri = getBaseURI(port);
httpServer = IHttpServerFactory.createHttpServer(uri,
new IHttpHandler(null));
TCPNIOTransport transport = getListener(httpServer).getTransport();
ThreadPoolConfig config = ThreadPoolConfig.defaultConfig()
.setPoolName("worker-thread-").setCorePoolSize(6).setMaxPoolSize(6)
.setQueueLimit(-1)/* same as default */;
transport.configureBlocking(false);
transport.setSelectorRunnersCount(3);
transport.setWorkerThreadPoolConfig(config);
transport.setIOStrategy(WorkerThreadIOStrategy.getInstance());
transport.setTcpNoDelay(true);
System.out.println("Blocking Transport(T/F): " + transport.isBlocking());
System.out.println("Num SelectorRunners: "
+ transport.getSelectorRunnersCount());
System.out.println("Num WorkerThreads: "
+ transport.getWorkerThreadPoolConfig().getCorePoolSize());
httpServer.start();
System.out.println("Server Started #" + uri.toString());
}
public static void main(String[] args) throws InterruptedException,
IOException, InstantiationException, IllegalAccessException,
ClassNotFoundException {
startHttpServer(7777);
System.out.println("Press any key to stop the server...");
System.in.read();
}
private static NetworkListener getListener(HttpServer httpServer) {
return httpServer.getListeners().iterator().next();
}
private static URI getBaseURI(int port) {
return UriBuilder.fromUri("https://0.0.0.0/").port(port).build();
}
}
HttpHandler (with async support built in)
package com.grizzly.http;
import java.io.IOException;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import javax.ws.rs.core.Application;
import org.glassfish.grizzly.http.server.HttpHandler;
import org.glassfish.grizzly.http.server.Request;
import org.glassfish.grizzly.http.server.Response;
import org.glassfish.grizzly.http.util.HttpStatus;
import org.glassfish.grizzly.threadpool.GrizzlyExecutorService;
import org.glassfish.grizzly.threadpool.ThreadPoolConfig;
import org.glassfish.jersey.server.ApplicationHandler;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.spi.Container;
import com.grizzly.Utils;
/**
* Jersey {#code Container} implementation based on Grizzly
* {#link org.glassfish.grizzly.http.server.HttpHandler}.
*
* #author Jakub Podlesak (jakub.podlesak at oracle.com)
* #author Libor Kramolis (libor.kramolis at oracle.com)
* #author Marek Potociar (marek.potociar at oracle.com)
*/
public final class IHttpHandler extends HttpHandler implements Container {
private static int reqNum = 0;
final ExecutorService executorService = GrizzlyExecutorService
.createInstance(ThreadPoolConfig.defaultConfig().copy()
.setCorePoolSize(4).setMaxPoolSize(4));
private volatile ApplicationHandler appHandler;
/**
* Create a new Grizzly HTTP container.
*
* #param application
* JAX-RS / Jersey application to be deployed on Grizzly HTTP
* container.
*/
public IHttpHandler(final Application application) {
}
#Override
public void start() {
super.start();
}
#Override
public void service(final Request request, final Response response) {
System.out.println("\nREQ_ID: " + reqNum++);
System.out.println("THREAD_ID: " + Utils.getThreadName());
response.suspend();
// Instruct Grizzly to not flush response, once we exit service(...) method
executorService.execute(new Runnable() {
#Override
public void run() {
try {
System.out.println("Executor Service Current THREAD_ID: "
+ Utils.getThreadName());
Thread.sleep(25 * 1000);
} catch (Exception e) {
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR_500);
} finally {
String content = updateResponse(response);
System.out.println("Response resumed > " + content);
response.resume();
}
}
});
}
#Override
public ApplicationHandler getApplicationHandler() {
return appHandler;
}
#Override
public void destroy() {
super.destroy();
appHandler = null;
}
// Auto-generated stuff
#Override
public ResourceConfig getConfiguration() {
return null;
}
#Override
public void reload() {
}
#Override
public void reload(ResourceConfig configuration) {
}
private String updateResponse(final Response response) {
String data = null;
try {
data = new Date().toLocaleString();
response.getWriter().write(data);
} catch (IOException e) {
data = "Unknown error from our server";
response.setStatus(500, data);
}
return data;
}
}
IHttpServerFactory.java
package com.grizzly.http;
import java.net.URI;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.grizzly.http.server.NetworkListener;
import org.glassfish.grizzly.http.server.ServerConfiguration;
/**
* #author smc
*/
public class IHttpServerFactory {
private static final int DEFAULT_HTTP_PORT = 80;
public static HttpServer createHttpServer(URI uri, IHttpHandler handler) {
final String host = uri.getHost() == null ? NetworkListener.DEFAULT_NETWORK_HOST
: uri.getHost();
final int port = uri.getPort() == -1 ? DEFAULT_HTTP_PORT : uri.getPort();
final NetworkListener listener = new NetworkListener("IGrizzly", host, port);
listener.setSecure(false);
final HttpServer server = new HttpServer();
server.addListener(listener);
final ServerConfiguration config = server.getServerConfiguration();
if (handler != null) {
config.addHttpHandler(handler, uri.getPath());
}
config.setPassTraceRequest(true);
return server;
}
}
It seems the problem is the browser waiting for the first request to complete, and thus more a client-side than a server-side issue. It disappears if you test with two different browser processes, or even if you open two distinct paths (let's say localhost:7777/foo and localhost:7777/bar) in the same browser process (note: the query string partecipates in making up the path in the HTTP request line).
How I understood it
Connections in HTTP/1.1 are persistent by default, ie browsers recycle the same TCP connection over and over again to speed things up. However, this doesn't mean that all requests to the same domain will be serialized: in fact, a connection pool is allocated on a per-hostname basis (source). Unfortunately, requests with the same path are effectively enqueued (at least on Firefox and Chrome) - I guess it's a device that browsers employ to protect server resources (and thus user experience)
Real-word applications don't suffer from this because different resources are deployed to different URLs.
DISCLAIMER: I wrote this answer based on my observations and some educated guess. I think things may actually be like this, however a tool like Wireshark should be used to follow the TCP stream and definitely assert this is what happens.

How To Read Chrome Cookies Using Java

I am currently trying to read a certain cookie from my Java desktop application. I have used a chrome extension to create the cookie and using the chrome console I can view that it has been created and has the correct value.
The problem arises when I try to read it from my Java application, my current code gets 3 seemingly random cookies, which wouldn't be a problem if it included mine. I have ensured my cookie is not host only and it is not secure, it actually has the same properties as the other 3 but it just is not being returned.
Here's my current code:
Java Application Code:
import java.io.IOException;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.CookieStore;
import java.net.URL;
import java.net.URLConnection;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* #author Spud
*/
public class Reading_My_Created_Cookie
{
/**
* #param args the command line arguments
*/
private static final String SEARCH_TERM = "Tab";
private static final String ADDRESS = "http://www.youtube.com/";
private static final CookieManager COOKIEMANAGER = new CookieManager();
private static Object myCookie;
public static void main(String[] args)
{
try
{
COOKIEMANAGER.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(COOKIEMANAGER);
URL url = new URL(ADDRESS);
URLConnection connection = url.openConnection();
connection.getContent();
CookieStore cookieStore = COOKIEMANAGER.getCookieStore();
Object[] cookieJar = cookieStore.getCookies().toArray();
for (int i = 0; i < cookieJar.length; ++i)
{
System.out.println(cookieJar[i]);
}
//myCookie = checkForCookie(cookieJar);
//System.out.println(myCookie);
}
catch (IOException ex)
{
Logger.getLogger(Reading_My_Created_Cookie.class.getName()).log(Level.SEVERE, null, ex);
}
}
private static Object checkForCookie(Object[] cookieJar)
{
for (int i = 0; i < cookieJar.length; ++i)
{
if (cookieJar[i].equals(SEARCH_TERM))
{
return cookieJar[i];
}
}
return "Cookie not found";
}
}
This currently outputs the following:
run:
YSC=6EIDrzvf02s
PREF=f1=50000000
VISITOR_INFO1_LIVE=qKCoNVZQMi8
BUILD SUCCESSFUL (total time: 4 seconds)
For anyone who wants it, this is my current extension JavaScript code:
chrome.browserAction.onClicked.addListener(run);
function run()
{
var cookieName, cookieValue, cookieURL;
cookieName = "Tab";
chrome.tabs.getSelected(null, function(tab)
{
cookieValue = tab.title;
cookieURL = tab.url;
createCookie(cookieName, cookieValue, cookieURL);
});
}
function createCookie(cookieName, cookieValue, cookieURL)
{
chrome.cookies.set({name: cookieName, value: cookieValue, domain: ".youtube.com", url: cookieURL});
alert("cookieName = " + cookieName + " cookieValue/tabTitle = " + cookieValue + " tabURL = " + cookieURL);
}
Thank you for your time, I really hope I can get this sorted as it is currently a key part of my A-level computing project.

NoClassDefFoundError and Netty

First to say I'm n00b in Java. I can understand most concepts but in my situation I want somebody to help me. I'm using JBoss Netty to handle simple http request and using MemCachedClient check existence of client ip in memcached.
import org.jboss.netty.channel.ChannelHandler;
import static org.jboss.netty.handler.codec.http.HttpHeaders.*;
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.*;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.*;
import static org.jboss.netty.handler.codec.http.HttpVersion.*;
import com.danga.MemCached.*;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.handler.codec.http.Cookie;
import org.jboss.netty.handler.codec.http.CookieDecoder;
import org.jboss.netty.handler.codec.http.CookieEncoder;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpChunk;
import org.jboss.netty.handler.codec.http.HttpChunkTrailer;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
import org.jboss.netty.handler.codec.http.QueryStringDecoder;
import org.jboss.netty.util.CharsetUtil;
/**
* #author The Netty Project
* #author Andy Taylor (andy.taylor#jboss.org)
* #author Trustin Lee
*
* #version $Rev: 2368 $, $Date: 2010-10-18 17:19:03 +0900 (Mon, 18 Oct 2010) $
*/
#SuppressWarnings({"ALL"})
public class HttpRequestHandler extends SimpleChannelUpstreamHandler {
private HttpRequest request;
private boolean readingChunks;
/** Buffer that stores the response content */
private final StringBuilder buf = new StringBuilder();
protected MemCachedClient mcc = new MemCachedClient();
private static SockIOPool poolInstance = null;
static {
// server list and weights
String[] servers =
{
"lcalhost:11211"
};
//Integer[] weights = { 3, 3, 2 };
Integer[] weights = {1};
// grab an instance of our connection pool
SockIOPool pool = SockIOPool.getInstance();
// set the servers and the weights
pool.setServers(servers);
pool.setWeights(weights);
// set some basic pool settings
// 5 initial, 5 min, and 250 max conns
// and set the max idle time for a conn
// to 6 hours
pool.setInitConn(5);
pool.setMinConn(5);
pool.setMaxConn(250);
pool.setMaxIdle(21600000); //1000 * 60 * 60 * 6
// set the sleep for the maint thread
// it will wake up every x seconds and
// maintain the pool size
pool.setMaintSleep(30);
// set some TCP settings
// disable nagle
// set the read timeout to 3 secs
// and don't set a connect timeout
pool.setNagle(false);
pool.setSocketTO(3000);
pool.setSocketConnectTO(0);
// initialize the connection pool
pool.initialize();
// lets set some compression on for the client
// compress anything larger than 64k
//mcc.setCompressEnable(true);
//mcc.setCompressThreshold(64 * 1024);
}
#Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
HttpRequest request = this.request = (HttpRequest) e.getMessage();
if(mcc.get(request.getHeader("X-Real-Ip")) != null)
{
HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
response.setHeader("X-Accel-Redirect", request.getUri());
ctx.getChannel().write(response).addListener(ChannelFutureListener.CLOSE);
}
else {
sendError(ctx, NOT_FOUND);
}
}
private void writeResponse(MessageEvent e) {
// Decide whether to close the connection or not.
boolean keepAlive = isKeepAlive(request);
// Build the response object.
HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
response.setContent(ChannelBuffers.copiedBuffer(buf.toString(), CharsetUtil.UTF_8));
response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8");
if (keepAlive) {
// Add 'Content-Length' header only for a keep-alive connection.
response.setHeader(CONTENT_LENGTH, response.getContent().readableBytes());
}
// Encode the cookie.
String cookieString = request.getHeader(COOKIE);
if (cookieString != null) {
CookieDecoder cookieDecoder = new CookieDecoder();
Set<Cookie> cookies = cookieDecoder.decode(cookieString);
if(!cookies.isEmpty()) {
// Reset the cookies if necessary.
CookieEncoder cookieEncoder = new CookieEncoder(true);
for (Cookie cookie : cookies) {
cookieEncoder.addCookie(cookie);
}
response.addHeader(SET_COOKIE, cookieEncoder.encode());
}
}
// Write the response.
ChannelFuture future = e.getChannel().write(response);
// Close the non-keep-alive connection after the write operation is done.
if (!keepAlive) {
future.addListener(ChannelFutureListener.CLOSE);
}
}
#Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
throws Exception {
e.getCause().printStackTrace();
e.getChannel().close();
}
private void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) {
HttpResponse response = new DefaultHttpResponse(HTTP_1_1, status);
response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8");
response.setContent(ChannelBuffers.copiedBuffer(
"Failure: " + status.toString() + "\r\n",
CharsetUtil.UTF_8));
// Close the connection as soon as the error message is sent.
ctx.getChannel().write(response).addListener(ChannelFutureListener.CLOSE);
}
}
When I try to send request like http://127.0.0.1:8090/1/2/3
I'm getting
java.lang.NoClassDefFoundError: com/danga/MemCached/MemCachedClient
at httpClientValidator.server.HttpRequestHandler.<clinit>(HttpRequestHandler.java:66)
I believe it's not related to classpath. May be it's related to context in which mcc doesn't exist.
Any help appreciated
EDIT:
Original code http://docs.jboss.org/netty/3.2/xref/org/jboss/netty/example/http/snoop/package-summary.html
I've modified some parts to fit my needs.
Why do you think this is not classpath related? That's the kind of error you get when the jar you need is not available. How do you start your app?
EDIT
Sorry - i loaded and tried the java_memcached-release_2.5.2 bundle in eclipse and found no issue so far. Debugging the class loading revealed nothing unusual. I can't help besides some more hints to double check:
make sure your download is correct. download and unpack again. (are the com.schooner.* classes available?)
make sure you use > java 1.5
make sure your classpath is correct and complete. The example you have shown does not include netty. Where is it.
I'm not familiar with interactions stemming from adding a classpath to the manifest. Maybe revert to plain style, add all jars needed (memcached, netty, yours) to the classpath and reference the main class to start, not a startable jar file

Categories