HttpPostのsetHeaderで「Authorization」ヘッダーを設定すると、ホスト名がリクエストから消え、常にエラー400(不正なリクエスト)が返されます。同じコードが純粋なJava(Androidなし))で正常に機能しており、Androidでも "Authorization"ヘッダーの設定を削除すると正常に機能しますが、認証が必要です。これはコードです(ドメインが変更されました):
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://myhost.com/test.php");
post.setHeader("Accept", "application/json");
post.setHeader("User-Agent", "Apache-HttpClient/4.1 (Java 1.5)");
post.setHeader("Host", "myhost.com");
post.setHeader("Authorization",getB64Auth());
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("data[body]", "test"));
AbstractHttpEntity ent=new UrlEncodedFormEntity(nvps, HTTP.UTF_8);
ent.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
ent.setContentEncoding("UTF-8");
post.setEntity(ent);
post.setURI(new URI("http://myhost.com/test.php"));
HttpResponse response =client.execute(post);
メソッドgetB64Auth()は、 "YnxpcYRlc3RwMTulHGhlSGs ="のようにBase64を使用してエンコードされた "login:password"を返しますが、重要ではありません。
これは、上記のコードが純粋なJavaで呼び出されたときのlighttpdのerror.logの一部です。
2011-02-23 15:37:36: (request.c.304) fd: 8 request-len: 308
POST /test.php HTTP/1.1
Accept: application/json
User-Agent: Apache-HttpClient/4.1 (Java 1.5)
Host: myhost.com
Authorization: Basic YnxpcYRlc3RwMTulHGhlSGs=
Content-Length: 21
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Encoding: UTF-8
Connection: Keep-Alive
HTTP/1.1 200 OK
Content-type: text/html
Transfer-Encoding: chunked
およびaccess.logからの記録(IPが変更されました):
1.1.1.1 myhost.com - [23/Feb/2011:15:37:36 +0100] "POST /test.php HTTP/1.1" 200 32 "-" "Apache-HttpClient/4.1 (Java 1.5)"
同じコードがAndroidで呼び出されると、ログで次のようになります。
POST /test.php HTTP/1.1
Accept: application/json
User-Agent: Apache-HttpClient/4.1 (Java 1.5)
Host: myhost.com
Authorization: Basic YnxpcYRlc3RwMTulHGhlSGs=
Content-Length: 21
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Encoding: UTF-8
Connection: Keep-Alive
Expect: 100-Continue
2011-02-23 15:45:10: (response.c.128) Response-Header:
HTTP/1.1 400 Bad Request
Content-Type: text/html
Content-Length: 349
Connection: close
access.log:
1.1.1.1 - - [23/Feb/2011:15:45:10 +0100] "POST /test.php HTTP/1.1" 400 349 "-" "Apache-HttpClient/4.1 (Java 1.5)"
POSTで承認を取得する方法は?Androidで動作していますか?HttpClientの代わりにHttpURLConnectionを使用する場合、違いはありません。
ヒントをくれたSamuhに感謝します:) GETリクエストでは意味がありませんが、POSTで重要な余分な改行文字が挿入されました。これは、AndroidでAuthorizationヘッダーを生成する適切な方法です(この場合はgetB64Authで):
private String getB64Auth (String login, String pass) {
String source=login+":"+pass;
String ret="Basic "+Base64.encodeToString(source.getBytes(),Base64.URL_SAFE|Base64.NO_WRAP);
return ret;
}
Base64.NO_WRAPフラグがありませんでした。
単にこれを使用してください:
String authorizationString = "Basic " + Base64.encodeToString(
("your_login" + ":" + "your_password").getBytes(),
Base64.NO_WRAP); //Base64.NO_WRAP flag
post.setHeader("Authorization", authorizationString);