2009年4月9日星期四

Google App Engine 开始支持 Java

Google App Engine 周年之际,终于推出了Java 版的SDK。Google 称其为 An Early Look at Java™ Language Support,并给出了一万个测试名额。

之所以称为 An Early Look 是因为对 Java 支持的开发还在进行中(原文: Our support for the Java language is still under development )。但这个 Early Look 还是足以满足广大开发者的好奇心了。

这个版本包括了 Googel 的 Java runtime、集成Google Web Toolkit、还有一个Eclipse插件。
更多信息可以参考 Google App Engine 英文站点

2009年3月7日星期六

goolge app engine 上传错误问题的解决办法

试用google app engine,开始还一切顺利。
后来不知为什么再用 appcfg.py update xxxx 的时候就一直报错。
提示信息 : ERROR appcfg.py:1235 An unexpected error occurred. 等等....

经过在 google 上的一番耕耘,终于在找到了解决办法。
首先进入用户目录 ( C:\Documents and Settings\user name )
删除 .appcfg_cookies 文件
一切恢复正常




2009年3月4日星期三

推荐免费支持外链没有广告的图片存储服务 Pict.com

Pict.com 是一家提供图片存储和分享服务的网站,相比其他一些图片存储服务 Pict.com 不限制存储空间、没有广告(这点很难得)、支持外链、不强制注册(可以不需注册直接使用他的服务)、完全免费、而且网站设计简介清爽,此外 Pict.com 还提供了 FireFox 插件,使用户可以更方便的使用优质的图片存储和分享服务。

点击下载 Pict.com FireFox 插件 (Click here to download)

Pict.com FireFox 插件的特性

  • 网站截图 (完整或选定区域)
  • 将截图保存为 jpg/png 格式 
  • 自动上传截图
  • 右键上传浏览器中的任何图片
  • 生成图片链接
  • 从本地上传图片等

2008年12月10日星期三

Yaml Builder 生成的 css 在Google Chrome 中无法正常显示的问题

Yaml Builder 是一个生成 Yaml Layout 的图形界面工具。用起来很方便,效果也不错。

试用Yaml Builder后发现,其生成的代码在Firefox、IE、和Opera下均能正常工作,但在Google Chrome下css不起作用。

Yaml Builder 生成的 css 如下:
@charset "UTF-8";
@media screen, projection
{
.....

最终找到问题所在,是【@charset "UTF-8";】 这句代码导致 Google Chrome 无法显示 css 样式,把这句删除之后就可以正常显示了。

【@charset "UTF-8";】made CSS not display correctly in Google Chrome, so remove 【@charset "UTF-8";】to solve this problem.

2008年10月15日星期三

c# 根据URL定位InternetCache中文件的位置

从IE浏览器缓存中根据URL定位本地文件有很多用处,比如直接从缓存中保存浏览过的图片,避免再次下载以节省带宽,另外在显示或保存验证码图片之类每次访问都会随机改变的文件时也很有用。但是由于在本地系统中浏览器缓存的临时文件并不是用一般方式保存的(具体参加MSDN),所以处理上稍微麻烦一些。

前段时间用 c# 写一个小程序时,使用如下代码获取指定URL文件缓存在本地文件系统中的临时文件的路径。

[DllImport("Wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern Boolean GetUrlCacheEntryInfo(String lpxaUrlName, IntPtr lpCacheEntryInfo, ref int lpdwCacheEntryInfoBufferSize);

const int ERROR_FILE_NOT_FOUND = 0x2;
struct LPINTERNET_CACHE_ENTRY_INFO
{
public int dwStructSize;
IntPtr lpszSourceUrlName;
public IntPtr lpszLocalFileName;
int CacheEntryType;
int dwUseCount;
int dwHitRate;
int dwSizeLow;
int dwSizeHigh;
FILETIME LastModifiedTime;
FILETIME Expiretime;
FILETIME LastAccessTime;
FILETIME LastSyncTime;
IntPtr lpHeaderInfo;
int dwheaderInfoSize;
IntPtr lpszFileExtension;
int dwEemptDelta;
}

// 返回 指定URL文件的缓存在本地文件系统中的路径
private string GetPathForCachedFile(string fileUrl)
{
int cacheEntryInfoBufferSize = 0;
IntPtr cacheEntryInfoBuffer = IntPtr.Zero;
int lastError; Boolean result;
try
{
result = GetUrlCacheEntryInfo(fileUrl, IntPtr.Zero, ref cacheEntryInfoBufferSize);
lastError = Marshal.GetLastWin32Error();
if (result == false)
{
if (lastError == ERROR_FILE_NOT_FOUND) return null;
}
cacheEntryInfoBuffer = Marshal.AllocHGlobal(cacheEntryInfoBufferSize);

result = GetUrlCacheEntryInfo(fileUrl, cacheEntryInfoBuffer, ref cacheEntryInfoBufferSize);
lastError = Marshal.GetLastWin32Error();
if (result == true)
{
Object strObj = Marshal.PtrToStructure(cacheEntryInfoBuffer, typeof(LPINTERNET_CACHE_ENTRY_INFO));
LPINTERNET_CACHE_ENTRY_INFO internetCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO)strObj;
String localFileName = Marshal.PtrToStringAuto(internetCacheEntry.lpszLocalFileName); return localFileName;
}
else return null;// file not found
}
finally
{
if (!cacheEntryInfoBuffer.Equals(IntPtr.Zero)) Marshal.FreeHGlobal(cacheEntryInfoBuffer);
}
}

2008年8月6日星期三

co.cc 难道又被封了?

我有个站用的是co.cc的免费域名,前段时间一直运行好好的,不过最近几天不能正常访问了。今天查了一下原因,发现连co.cc都ping不通了。用tor试了一下,我的网站和co.cc都可以正常访问,也就是说不出意外的话,co.cc应该是被河蟹了,不由得我想发发牢骚。网络应该是开放、自由的,不能老逼真人带着套(tor)啊。

CO.CC 提供免费二级域名注册,没有广告,支持隐藏或不隐藏原URL转发。提供完全DNS解析功能,可以修改DNS、设置A记录、CNAME记录、NS记录以及MX记录,还完全支持Google Apps企业邮局。如果给封了那实在是太可惜了,再说没几天就开奥运了,cnn都解封了,怎么能现在封co.cc呢?要封也应该等到国外的朋友们都走了不是吗?

2008年8月4日星期一

编程方式更改Tor身份——Switch TOR to a new identity

Tor 俗称洋葱路由器,用于防范流量过滤、嗅探分析,可以实现匿名对外连接、匿名隐藏服务。Tor 的代理一般在2-5层左右,加密程度也比较高。在一些需要使用代理的项目中用Tor 替代常用的代理服务器,有两个显著的好处:一是安全,二是可用代理非常多而且可靠性也很高。

在程序中使用Tor 的一个关键问题就是如何在程序中强制Tor 使用新的身份(切换代理),如果不能在程序中更换身份那使用Tor 的意义也就不大了。

Tor 默认HTTP代理端口是8118,Socket代理端口是9050,控制端口是9051。我们可以通过向Tor 控制端口发送命令来强制Tor 使用新的身份。

下面有三段代码,分别由shell、php和c#实现切换Tor 使用新的身份。

shell代码片段:
spawn telnet 127.0.0.1 9051
expect "Escape character is'^]'."
send "AUTHENTICATE\r"
expect "250 OK"
send "signal NEWNYM\r"
expect "250 OK"
send "quit\r"

php版本:
/** * Switch Tor to a new identity. **/
function tor_new_identity($tor_ip='127.0.0.1', $control_port='9051', $auth_code='')
{
$fp = fsockopen($tor_ip, $control_port, $errno, $errstr, 30);
if (!$fp) return false; //can't connect to the control port
fputs($fp, "AUTHENTICATE $auth_code\r\n");
$response = fread($fp, 1024);
list($code, $text) = explode(' ', $response, 2);
if ($code != '250')
return false; //authentication failed

//send the request to for new identity
fputs($fp, "signal NEWNYM\r\n");
$response = fread($fp, 1024);
list($code, $text) = explode(' ', $response, 2);
if ($code != '250') return false; //signal failed
fclose($fp); return true;
}
?>

c#版本代码片段:
TcpClient client = new TcpClient();
client.Connect("127.0.0.1", Convert.ToInt32(9051));
NetworkStream stream = client.GetStream();
byte[] cmd = null;
string strCmd = string.Format("AUTHENTICATE \"{0}\"\r\n",password);
cmd = System.Text.Encoding.Default.GetBytes(strCmd);
stream.Write(cmd, 0, cmd.Length);
byte[] buffer = new byte[2];
int count = 0;
string strResponse = "";
count = stream.Read(buffer, 0, buffer.Length);
strResponse += System.Text.Encoding.Default.GetString(buffer, 0, count);
while (count != 0 && stream.DataAvailable)
{
count = stream.Read(buffer, 0, buffer.Length);
strResponse += System.Text.Encoding.Default.GetString(buffer, 0, count);
if (count < buffer.Length)
break;
}
if (strResponse.IndexOf("250") == -1)
{
MessageBox.Show("AUTHENTICATE Fail!");
return;
}
buffer = new byte[1024];
strCmd = "signal NEWNYM\r\n";
cmd = System.Text.Encoding.Default.GetBytes(strCmd);
stream.Write(cmd, 0, cmd.Length);
strResponse = "";
count = stream.Read(buffer, 0, buffer.Length);
strResponse += System.Text.Encoding.Default.GetString(buffer, 0, count);
while (count != 0 && stream.DataAvailable)
{
count = stream.Read(buffer, 0, buffer.Length);
strResponse += System.Text.Encoding.Default.GetString(buffer, 0, count);
if (count < buffer.Length)
break;
}
if (strResponse.IndexOf("250") == 1)
MessageBox.Show("Switch Identity OK!");

参考文章地址:
http:// linux.chinaunix.net/bbs/thread-1014409-1-1.html
http:// w-shadow.com/blog/2008/06/20/tor-how-to-new-identity-with-php
http:// www.cnblogs.com/sxlfybb/archive/2008/07/07/1237662.html