posted in Java 

This page show you why we need to disable TRACE HTTP method for security reason. And provide a sample project to show you how to disable TRACE in embedded Jetty.

Why we need to disable TRACE method

Allowing TRACE method will leads to Cross-Site Tracking (a.k.a XST) problem. XST was found in 2003. It’s a very old topic and I can’t get any new discussion after searched in Google. But it’s good to disable TRACE for our server to avoid any redundant endpoint exposes to the danger world.

Avoid XST Attack

As we all know, server will echo back all information when it receive TRACE request. “All information” means the cookies, the credential data and the server version etc. When user is visiting a malicious website, a hacker can read malicious data by calling a cross-site TRACE request.

Limit Information Expose to the World

In the other case, we run an API server which user will not access by browser directly. It’s good practice to limit the information expose to the external world. Information like version may tell others which issue is ok to use to hack. If we don’t need TRACE (at lease in production environment), so disable it.

How to disable TRACE in Embedded Jetty

By default Jetty enables TRACE and we need to disable it manually.
This GitHub project shows you how to disable TRACE for embedded Jetty.

private Handler wrapWithSecurityHandler(Handler h){
        Constraint disableTraceConstraint = new Constraint();
        disableTraceConstraint.setName("Disable TRACE");
        disableTraceConstraint.setAuthenticate(true);

        ConstraintMapping mapping = new ConstraintMapping();
        mapping.setConstraint(disableTraceConstraint);
        mapping.setMethod("TRACE");
        mapping.setPathSpec("/");

        // omissionConstraint is to fix the warning log ""null has uncovered http methods for path: /
        // No impact to disable TRACE if you do not add this constraint
        // But if you're using the monitoring tool like Geneos, and your component requires keep production monitoring all green,
        // You can try to add this omissionConstraint to fix the warning Jetty prints.
        Constraint omissionConstraint = new Constraint();
        ConstraintMapping omissionMapping = new ConstraintMapping();
        omissionMapping.setConstraint(omissionConstraint);
        omissionMapping.setMethod("*");
        omissionMapping.setPathSpec("/");


        ConstraintSecurityHandler handler = new ConstraintSecurityHandler();
        handler.addConstraintMapping(mapping);
        handler.addConstraintMapping(omissionMapping);
        handler.setHandler(h);
        return handler;
    }

Also notice that I wrote omissionConstraint, applied to all method to fix a warning Jetty prints:
null has uncovered http methods for path: /

If you’r not required to keep production monitoring all green, you can delete this redundant constraint and accept this warning.

References

[1] CROSS-SITE TRACING (XST) - THE NEW TECHNIQUES AND EMERGING THREATS TO BYPASS CURRENT WEB SECURITY MEASURES USING TRACE AND XSS - Jeremiah Grossman
[2] Cross Site Tracing - OWASP
[3] spring - Java embedded jetty is accepting HTTP TRACE method - Stack Overflow

posted in Others 

在中国,使用 Windows 的远程桌面服务有两个困难。

  1. 官方的 Remote Desktop Client on Mac 不在中国销售。
  2. 家庭版的 Windows 10 不包含远程桌面服务。

解决方法是两个都找第三方解决方案。

  1. 使用 Parallels Client 代替 Remote Desktop Client on Mac
  2. 适用 rdpwrap 提供远程桌面服务

安装 Parallels Client

Parallels Client: https://itunes.apple.com/us/app/parallels-client/id600925318?mt=12

或者需要付费但是一样更好功能更加强大的 Parallels Access:
http://www.parallels.com/cn/products/access/

安装 rdpwrap

GitHub: https://github.com/stascorp/rdpwrap

rdpwrap 是在家庭版 Windows 上提供远程桌买服务的一个开源项目。支持从 Windows Vista 到 Windows 10 系统。安装和使用说明请到 GitHub 主页查看。

posted in Angular 

It's very easy to make a mistake on Angular2 router. After refresh the page, the page to be routed to can not load successfully. Chrome console tell me that browser failed to load css resources as the path of resources is incorrect.

The solution is that put the <base href="/"/> directly under the title tag.

posted in iOS 

Days ago I update pod to version 1.0. Then found all header not found in my header bridge file. I spent 2 days to locate the reason. That is cocoaPods.
Thanks to Git, I noticed that Header folder was be deleted after I run pod install which pod 0.x did not do that.
What pod 1.0 do is that I don’t need import headers explicitly any more. Pod do that.
So what I need to do is DELETE all import statement which not found. That will fix everything.

posted in Angular 

When I type npm start in my angular2 project, terminal shows:

Subsequent variable declarations must have the same type. Variable '$' must be of type 'JQueryStatic', but here has type 'cssSelectorHelper'
There is a conflict between angular-protractor and jQuery. One soluction I googled is marked down below:

Modify your jquery.d.ts file
From:

declare module "jquery" {
    export = $;
}
declare var jQuery: JQueryStatic;
declare var $: JQueryStatic;

To:

declare module "jquery" {
    export = jQuery;
}
declare var jQuery: JQueryStatic;

On the contrary, you can change protractor also.
References:
[1] How to use jquery with angular2

posted in Android 

这么重要的问题竟然没有事先说明,太过分了。
今天更新了 Android 6.0 的 SDK 后发现项目一片红,吓尿了。
直接引用把:http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-apache-http-client
Android 6.0 release removes support for the Apache HTTP client. If your app is using this client and targets Android 2.3 (API level 9) or higher, use the HttpURLConnection class instead. This API is more efficient because it reduces network use through transparent compression and response caching, and minimizes power consumption. To continue using the Apache HTTP APIs, you must first declare the following compile-time dependency in your build.gradle file:

android {
    useLibrary 'org.apache.http.legacy'
}

大概意思就是,Android 6.0不再支持 Apache HTTP client。 请使用 HttpURLConnection 代替。想要继续使用 Apache HTTP client 的,请添加如上代码。

posted in Swift 

ObjectMapper is a swift library like Gson in Java. Using ObjectMapper, I can easily convert basic classes into JSON format string or convert it inversely.

The code below shows how to convert swift array into JSON and also recover it from JSON.

class Book: Mappable{
    var id:Int?
    var title:String?
    var category:[String]?
    
    init(id:Int, title:String, category:[String]){
        self.id = id
        self.title = title
        self.category = category
    }
    
    required init?(_ map: Map) {
        
    }
    
    func mapping(map: Map) {
        id          <- map["id"]
        title       <- map["title"]
        category    <- map["category"]
    }
}


// Do the conversion
let JSON = "{\"id\":3, \"title\":\"The Third Book\", \"category\":[\"TOP\", \"TECH\"]}"

// Convert JSON to class instance
let book3 = Mapper<Book>().map(JSON)!

let book1 = Book(id: 1, title: "The First Book", category: ["TECH"])
let book2 = Book(id: 2, title: "The Second Book", category: ["ART","MUSIC"])
let books = [book1, book2, book3]
   
// Convert array to JSON array string
let arrayJSON = Mapper().toJSONString(books, prettyPrint: true)

// Convert JSON array back to the array
let bookArray = Mapper<Book>().mapArray(arrayJSON)

TAG: ObjectMapper, JSON, Swift, Array, Convert, Conversion

posted in Swift  iOS 

The class NSDateFormatter is an easy-to-use tool. Just like SimpleDateFormat in Java.

Convert String to NSDate

let str = "2016-06-01T00:00:00Z"
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
let date = dateFormatter.dateFromString(str)

Convert NSDate to String

let description = "Time is \(dateFormatter.stringFromDate(date))"

TAG: Convert, String, NSDate, NSDateFormatter

posted in Java 

Integer 是 Java 5 引入的新特性,该特性能节省内存和改善性能。同样被引入缓存机制的还有 Byte,Short,Long,Character,缓存范围都是在 [-128,127] (Character是在[0,127])之间。

但是有几点需要注意的是:
1. 对 Integer 对象引入了 IntegerCache 类,其他封装类型也有对应的 XxxCache。
2. 该缓存特性只有在 autoboxing 过程中使用,换言之,使用 constructor 创建的 Integer 并不能被缓存。
3. 因为缓存机制的存在,在缓存范围内的对象都来自同一个缓存。带来的副作用是使用“==”地址比较运算符比较两个看似不一样的对象,得到的是 true。网上其他文章的说法是因而可以使用 == 来比较直接比较两个对象的值。但我觉得这样理解容易造成偏差。Java 规范并没有约定 [-128,127] 的范围内 == 用作值比较,这只是一个副作用。
4. 只有 Integer 对象可以通过指定 JVM 启动参数来修改缓存上限。

-XX:AutoBoxCacheMax=size

所以说写代码的时候还是不要把==用作值比较。
 
老实说这个缓存特性带来的不一致性要是导致了什么BUG实在很难排查。当用了这个特性写了点什么之后,难保后来者不会产生迷惑。所以日常编码中还是尽量避开这个点。
 
简单到爆的实验代码:
简单地验证Java Integer缓存特性

import com.sun.istack.internal.NotNull;
 
/**
 * Created by Lawrence on 15/11/9.
 */
public class Main {
    public static void main(String[] argv){
        Integer int1 = 100;
        Integer int2 = 100;
 
        if(int1==int2){
            print("int1 is equal to int2");
        } else {
            print("int1 is not equal to int2");
        }
        // prints "int1 is equal to int2"
 
        Integer int3 = 2333;
        Integer int4 = 2333;
 
        if(int3==int4){
            print("int3 is equal to int4");
        } else {
            print("int3 is not equal to int4");
        }
        // prints "int3 is not equal to int4"
 
        Integer int5 = 100;
        Integer int6 = new Integer(100);
 
        if(int5==int6){
            print("int5 is equal to int6");
        } else {
            print("int5 is not equal to int6");
        }
        // prints "int5 is not equal to int6"
    }
 
    public static void print(String str){
        System.out.println(str);
    }
 
}
posted in JavaScript 

这是由荷兰程序员 Gabor de Mooij 提出的一种比较简单的方法。Gabor de Mooij 称之为 minimalist approach。现摘录如下:

定义一个 Foo 类
var Foo = {
    createNew: function(){
        var instance = {};
        instance.description = "A new class instance";
        instance.bar = function() { console.log(instance.description)};
        return instance;
    }
}
创建一个 Foo 实例
var foo = Foo.createNew();
foo.bar();
类的继承
var NewFoo = {
    createNew = function(){
        var instance = Foo.createNew();
        instance.title = "A new title";
        instance.newBar = function(){
            alert(instance.description);
        };
    }
}
私有方法和属性
var Foo = {
    createNew: function(){
        var instance = {};
        instance.description = "A new class instance"; //description 是私有的,只有通过 bar() 来访问
        instance.bar = function() { console.log(instance.description)};
        return instance;
    }
}
静态成员变量
var Foo = {
    id: 101010; // id 在多个实例间共享
    createNew: function(){
        var instance = {};
        instance.description = "A new class instance"; //description 是私有的,只有通过 bar() 来访问
        instance.bar = function() { console.log(instance.description)};
        return instance;
    }
}

var foo1 = Foo.createNew();
var foo2 = Foo.createNew();
foo2.id = 233333;
console.log("Foo id:"+foo1.id);