public static Map send()

in groovy/src/main/resources/HTTP.groovy [87:195]


	public static Map<String,Object> send(Map<String,Object> ctx)throws IOException{
		String             url      = ctx.url;
		Map<String,String> headers  = (Map<String,String>)ctx.headers;
		String             method   = ctx.method;
		Object             body     = ctx.body;
		String             encoding = ctx.encoding?:"UTF-8";
		Closure            receiver = (Closure)ctx.receiver;
		Map<String,String> query    = (Map<String,String>)ctx.query;
		Object             sslCtxObj= ctx.ssl;
		
		//copy context and set default values
		ctx = [:] + ctx;
		ctx.encoding = encoding;
		String contentType="";
		
		if(query){
			url+="?"+query.collect{k,v-> k+"="+URLEncoder.encode(v,'UTF-8') }.join('&')
		}
		
		HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
		if(sslCtxObj!=null && connection instanceof HttpsURLConnection){
			SSLContext         sslCtx   = null;
			if(sslCtxObj instanceof SSLContext){
				sslCtx = (SSLContext)sslCtxObj;
			}else if(sslCtxObj instanceof CharSequence){
				//assume this is a groovy code to get ssl context
				sslCtx = evaluateSSLContext((CharSequence)sslCtxObj);
			}else{
				throw new IllegalArgumentException("Unsupported ssl parameter ${sslCtxObj.getClass()}")
			}
			((HttpsURLConnection)connection).setSSLSocketFactory(sslCtx.getSocketFactory());
		}
		
        connection.setDoOutput(true);
        connection.setRequestMethod(method);
		if ( headers!=null && !headers.isEmpty() ) {
			//add headers
			for (Map.Entry<String, String> entry : headers.entrySet()) {
				if(entry.getValue()){
					connection.addRequestProperty(entry.getKey(), entry.getValue());
					if("content-type".equals(entry.getKey().toLowerCase()))contentType=entry.getValue();
				}
			}
		}
		
		if(body!=null){
			//write body
			OutputStream out = connection.getOutputStream();
			if( body instanceof Closure ){
				((Closure)body).call(out, ctx);
			}else if(body instanceof InputStream){
				out << (InputStream)body;
			}else if(body instanceof Map){
				if( contentType =~ "(?i)[^/]+/json" ) {
					out.withWriter((String)ctx.encoding){
						it.append( JsonOutput.toJson((Map)body) );
					}
				} else if( contentType =~ "(?i)[^/]+/x-www-form-urlencoded" ) {
					out.withWriter((String)ctx.encoding) {
						it.append( ((Map)body).collect{k,v-> ""+k+"="+URLEncoder.encode((String)v,'UTF-8') }.join('&') )
					}
				} else {
					throw new IOException("Map body type supported only for */json of */x-www-form-urlencoded content-type");
				}
			}else if(body instanceof CharSequence){
				out.withWriter((String)ctx.encoding){
					it.append((CharSequence)body);
				}
			}else{
				throw new IOException("Unsupported body type: "+body.getClass());
			}
			out.flush();
			out.close();
			out=null;
		}
		
		Map response     = [:];
		ctx.response     = response;
		response.code    = connection.getResponseCode();
		response.message = connection.getResponseMessage();
		response.headers = connection.getHeaderFields();
		
		InputStream instr = null;
		
		if( ((int)response.code)>=400 ){
			try{
				instr = connection.getErrorStream();
			}catch(Exception ei){}
		}else{
			try{
				instr = connection.getInputStream();
			}catch(java.io.IOException ei){
				throw new IOException("fail to open InputStream for http code "+response.code+":"+ei);
			}
		}
		
		if(instr!=null) {
			instr = new BufferedInputStream(instr);
			if(receiver==null){
				if( response.headers['Content-Type']?.toString()?.indexOf('/json')>0 ){
					receiver=JSON_RECEIVER;
				} else receiver=TEXT_RECEIVER;
			}
			response.body = receiver(instr,ctx);
			instr.close();
			instr=null;
		}
		return ctx;
	}