Post data as coming from an HTML FORM with METHOD=POST to an url and retrieve the result. The procedure uses WinHttp.WinHttpRequest.5.1
2007-10-02 (first published: 2002-06-20)
15,444 reads
Post data as coming from an HTML FORM with METHOD=POST to an url and retrieve the result. The procedure uses WinHttp.WinHttpRequest.5.1
/* This is a procedure, not an udf because of the exec insert at the end The exec insert is needed because the response can exceed 8000 characters Normally, one should call methods like this : exec@rc = master.dbo.sp_OAMethod @http, 'Open', NULL, 'POST' ,'www.d-trix.com/default.asp', 0 But this does not work with WinHttp.WinHttpRequest.5.1 and gives different errors So we call methods like this exec@rc = master.dbo.sp_OAMethod @http, 'Open("POST","www.d-trix.com/default.asp",0)' if a (temp) table with the name #usp_httppost exists, the procedure will insert the result into that table. if not, the procedure will return a resultset with the results */create procedure dbo.usp_httppost ( @URL varchar(512) = '?', @post varchar(4000) = '', @WebLogin varchar(128) = null, @WebPassword varchar(128) = null, @ProxyLogin varchar(128) = null, @ProxyPassword varchar(128) = null ) /* returns @usp_httppost table ( return_status bit null, -- 0 is OK, 1 is error error_msg varchar(4096) null, HTTP_Status varchar(30) null, HTTP_AllResponseHeaders text null, HTTP_ResponseText text null ) */as begin if isnull(@URL,'?') = '?' begin print 'Name : usp_httppost' print 'Server : SQLserver 2000 ' print 'Description : Post data as coming from an HTML FORM with METHOD=POST' print ' to an URL and retrieve the result.' print 'Parameters : @URL : the url to use ( like https://www.d-trix.com )' print ' @post : the data to post' print ' @WebLogin : (optional) The Username for the webserver' print ' @WebPassword : (optional) The password for the webserver' print ' @ProxyLogin : (optional) The Username for the proxyserver' print ' @ProxyPassword : (optional) The password for the proxyserver' print 'Notes : . The data to be posted should be like param1=val1&par2=val2' print ' . if a table called #usp_httppost exists, the result is stored' print ' into that table. If not, the procedure returns a resultset.' print ' . The procedure also sets the option for winHTTP to ignore all' print ' ssl errors. You can comment this for security.' print ' . The procedure tries to use master.dbo.fn_hexadecimal to convert the' print ' sp_OA error to a hex string. If the UDF does not exists, it uses it''s' print ' own code to do the convertion.' print 'Date : 2005-01-19' print 'Author : Bert De Haes ( bertdehaes@scarlet.be )' print 'History : ' print 'Example : exec dbo.usp_httppost ''http://www.sqlservercentral.com/search/turbo.asp'',''searchstring=ftp&btnG= Go &cArticles=on&cForums=on&cScripts=on&sitesearch=http://www.sqlservercentral.com''' return 2 end set nocount on declare@http int, -- the objecttoken for WinHttp.WinHttpRequest.5.1 @rc int, -- the return code from sp_OA procedures @src varchar(255), -- the source of an error @desc varchar(512), -- the desciption of an error @Doing varchar(4000), -- What are we doing when calling a sp_OA proc @TableExisted bit, -- Did the temp table exists yes(1) or no(0) @HexError varchar(15) -- @rc converted to hexadecimal -- init set @rc = 0 if object_id('tempdb..#usp_httppost') is null begin -- The temp table #usp_httppost does not exists set @TableExisted = 0 create table #usp_httppost ( return_status bit null, -- 0 is OK, 1 is error error_msg varchar(4096) null, HTTP_Status varchar(30) null, HTTP_AllResponseHeaders text null, HTTP_ResponseText text null ) end else begin set @TableExisted = 1 truncate table #usp_httppost end -- Insert a default record insert#usp_httppost ( return_status, error_msg ) values( 1 , 'Unknown error' ) -- create a table to store output from different sp_OA calls create table #tempresult ( HTTP_Status varchar(30) null, HTTP_AllResponseHeaders text null, HTTP_ResponseText text null ) -- create the 'WinHttp.WinHttpRequest.5.1' object set@Doing= 'Create WinHttp.WinHttpRequest.5.1 object.' exec@rc= master.dbo.sp_OACreate 'WinHttp.WinHttpRequest.5.1', @http output if @rc <> 0 goto Error -- open the url on the server set@Doing = 'Open("POST" , "' + @URL + '", 0 )' exec@rc = master.dbo.sp_OAMethod @http, @Doing if @rc <> 0 goto Error -- set ignore ssl error set@Doing = 'Option' -- = 0x3300 exec@rc = master.dbo.sp_OASetProperty @http,@Doing,13056,4 if @rc <> 0 goto Error -- set the SetRequestHeader set @Doing = 'SetRequestHeader("Content-Type","application/x-www-form-urlencoded")' exec@rc = master.dbo.sp_OAMethod @http,@Doing if @rc <> 0 goto Error if @WebLogin is not null AND @WebPassword is not null begin -- Set the Credentials for the Webserver set@Doing = 'SetCredentials("' + @WebLogin + '","' + @WebPassword + '",0)' exec@rc = master.dbo.sp_OAMethod @http, @Doing if @rc <> 0 goto Error end if @ProxyLogin is not null AND @ProxyPassword is not null begin -- Set the Credentials for the Proxy set@Doing = 'SetCredentials("' + @ProxyLogin + '","' + @ProxyPassword + '",1)' exec@rc = master.dbo.sp_OAMethod @http, @Doing if @rc <> 0 goto Error end -- send the info set @Doing = 'Send("' + @post + '")' exec@rc = master.dbo.sp_OAMethod @http,@Doing if @rc <> 0 goto Error -- Get the HTTP_Status set@Doing = 'Status' truncate table#tempresult insert#tempresult (HTTP_Status) exec@rc = sp_OAMethod @http,@Doing if @rc <> 0 goto Error update#usp_httppost setHTTP_Status = #tempresult.HTTP_Status from#tempresult where#tempresult.HTTP_Status is not null -- Get the ResponseHeaders set@Doing = 'GetAllResponseHeaders' truncate table#tempresult insert#tempresult (HTTP_AllResponseHeaders) exec@rc = sp_OAMethod @http,@Doing if @rc <> 0 goto Error update#usp_httppost setHTTP_AllResponseHeaders = #tempresult.HTTP_AllResponseHeaders from#tempresult where#tempresult.HTTP_AllResponseHeaders is not null -- retrieve the ResponseText set@Doing = 'ResponseText' truncate table#tempresult insert#tempresult (HTTP_ResponseText) exec@rc = sp_OAMethod @http,@Doing if @rc <> 0 goto Error update#usp_httppost setHTTP_ResponseText = #tempresult.HTTP_ResponseText from#tempresult where#tempresult.HTTP_ResponseText is not null -- Everything went well update #usp_httppost set return_status = 0,error_msg = 'DONE' -- if we get here the normal way, don't do error GOTO Cleanup Error: -- Get error information if @http is not null begin exec sp_OAGetErrorInfo @http, @src OUT, @desc OUT end else begin set @src = '?' set @desc = '?' end if object_id('master.dbo.fn_hexadecimal') is null begin -- code for fn_hexadecimal here ... declare@i int, @length int, @hexstring char(16), @byte tinyint set @HexError = '0x' set @i = 1 set @length = DATALENGTH(cast (@rc as varbinary)) set @hexstring = '0123456789ABCDEF' while @i <= @length begin set @byte = convert(tinyint, substring(cast (@rc as varbinary),@i,1)) set @HexError = @HexError + substring(@hexstring, floor(@byte/16)+1, 1) + substring(@hexstring, (@byte % 16)+1, 1) set @i = @i + 1 end end else begin set @HexError = master.dbo.fn_hexadecimal(@rc) end update #usp_httppost setreturn_status = 1, error_msg = 'Error ['+ ISNULL( @HexError,'' ) + '], While ['+ ISNULL( @Doing, '' ) + '], Source ['+ ISNULL( @src , '' ) + '], Description ['+ ISNULL( @desc, '' ) + ']' -- Destroy created object(s) Cleanup: if @http is not null begin exec@rc= master.dbo.sp_OADestroy @http set @http = null if @rc <> 0 goto Error end -- Give the result back to the caller Result: if @TableExisted = 0 select * from #usp_httppost return 0 end