/*
 * Copyright 2008 Netflix, Inc.
 *
 * Licensed 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.
 */

package net.oauth.client;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
import net.oauth.OAuth;
import net.oauth.OAuthException;
import net.oauth.OAuthMessage;
import net.oauth.OAuthProblemException;

/**
 * Utility methods for an OAuth client based on URLConnection.
 * <p>
 * OAuthHttpClient performs better than this class, as a rule; since it does
 * things like connection pooling.
 * 
 * @author John Kristian
 */
public class OAuthURLConnectionClient extends OAuthClient {

    /** Send a message to the service provider and get the response. */
    @Override
    public OAuthMessage invoke(OAuthMessage request) throws IOException,
            OAuthException {
        final URL url = ("GET".equals(request.method)) //
        ? new URL(OAuth.addParameters(request.URL, request.getParameters())) //
                : new URL(request.URL);
        final URLConnection connection = url.openConnection();
        if (connection instanceof HttpURLConnection) {
            HttpURLConnection http = (HttpURLConnection) connection;
            http.setRequestMethod(request.method);
            http.setInstanceFollowRedirects(false);
        }
        connection.setDoInput(true);
        if (!"GET".equals(request.method)) {
            String form = OAuth.formEncode(request.getParameters());
            connection.setDoOutput(true);
            connection.setRequestProperty("Content-Type", OAuth.FORM_ENCODED);
            OutputStream output = connection.getOutputStream();
            try {
                Writer writer = new OutputStreamWriter(output, "ISO-8859-1");
                writer.write(form);
                writer.close();
            } finally {
                output.close();
            }
        }
        StringBuilder headers = new StringBuilder(request.method);
        {
            headers.append(" ").append(url.getPath());
            String query = url.getQuery();
            if (query != null && query.length() > 0) {
                headers.append("?").append(query);
            }
            headers.append("\n");
            for (Map.Entry<String, List<String>> header : connection
                    .getRequestProperties().entrySet()) {
                String key = header.getKey();
                for (String value : header.getValue()) {
                    headers.append(key).append(": ").append(value).append("\n");
                }
            }
        }
        final OAuthMessage response = new URLConnectionResponse(request,
                headers.toString(), connection);
        if (connection instanceof HttpURLConnection) {
            HttpURLConnection http = (HttpURLConnection) connection;
            int statusCode = http.getResponseCode();
            if (statusCode != HttpURLConnection.HTTP_OK) {
                Map<String, Object> dump = response.getDump();
                OAuthProblemException problem = new OAuthProblemException(
                        (String) dump.get(OAuthProblemException.OAUTH_PROBLEM));
                problem.getParameters().putAll(dump);
                throw problem;
            }
        }
        return response;
    }
}

@@ -1526,19 +1526,28 @@
 nal 
-URL url = (
+boolean sendBody = !
 %22GET
@@ -1546,32 +1546,42 @@
  = !%22GET%22.equals
+IgnoreCase
 (request.method)
@@ -1580,20 +1580,17 @@
 .method)
-) //
+;
 %0D%0A      
@@ -1595,62 +1595,66 @@
     
-? new URL(OAuth.addParameters(request.URL, request.get
+final URL url = new URL(sendBody ? request.URL : OAuth.add
 Para
@@ -1664,14 +1664,8 @@
 ers(
-))) //
 %0D%0A  
@@ -1682,26 +1682,29 @@
     
-: new URL(
+request.URL, 
 request.
 URL)
@@ -1699,19 +1699,32 @@
 request.
-URL
+getParameters())
 );%0D%0A    
@@ -2079,539 +2079,99 @@
 if (
-!%22GET%22.equals(request.method)) %7B%0D%0A            String form = OAuth.formEncode(request.getParameters());%0D%0A            connection.setDoOutput(true);%0D%0A            connection.setRequestProperty(%22Content-Type%22, OAuth.FORM_ENCODED);%0D%0A            OutputStream output = connection.getOutputStream();%0D%0A            try %7B%0D%0A                Writer writer = new OutputStreamWriter(output, %22ISO-8859-1%22);%0D%0A                writer.write(form);%0D%0A                writer.close();%0D%0A            %7D finally %7B%0D%0A                output.close();%0D%0A            %7D
+sendBody) %7B%0D%0A            connection.setRequestProperty(%22Content-Type%22, OAuth.FORM_ENCODED);
 %0D%0A  
@@ -2869,32 +2869,487 @@
   %7D%0D%0A        %7D%0D%0A
+        if (sendBody) %7B%0D%0A            String body = OAuth.formEncode(request.getParameters());%0D%0A            connection.setDoOutput(true);%0D%0A            OutputStream output = connection.getOutputStream();%0D%0A            try %7B%0D%0A                Writer writer = new OutputStreamWriter(output, %22ISO-8859-1%22);%0D%0A                writer.write(body);%0D%0A                writer.close();%0D%0A            %7D finally %7B%0D%0A                output.close();%0D%0A            %7D%0D%0A        %7D%0D%0A
         final OA

work with method = POST