Upload file to Amazon S3
<xsharper switchPrefixes="-">
<usage options="default ifNoArguments autoSuffix" />
<versionInfo version="1.0.0.0">Program to upload files to Amazon S3.</versionInfo>
<param name="directory" required="1">bucket/directory name</param>
<param name="files" required="1" count="multiple" description="file [file]">Files to upload</param>
<param />
<param>Either -secretkey or -secretkeyfile must be specified.</param>
<param switch="baseUrl" default="http://s3.amazonaws.com">Service URL</param>
<param switch="accesskey" required="1">Access key</param>
<param switch="secretkey">Secret key</param>
<param switch="secretkeyfile">Text file, first line of which contains the key</param>
<if isNotSet="secretKey">
<if isNotSet="secretkeyfile">
<throw>Either -secretkey or -secretkeyfile must be specified.</throw>
</if>
<set secretKey="${=.ReadLines($secretKeyFile)[0].Trim()}" />
</if>
<foreach file="${files}">
<print outTo="^info" nl="false">Uploading ${file} ...</print>
<code />
<set md5="${=X.FileMD5($file)}" />
<set url="${=X.SignUrl($baseUrl,$accesskey,$secretkey,$directory,$file,$md5)}" />
<print outTo="^debug">${url}</print>
<code>
try
{
System.Net.ServicePointManager.Expect100Continue = true;
using (XS.WebClientEx w=new XS.WebClientEx())
{
w.Headers.Add(HttpRequestHeader.ContentMd5, c.GetStr("md5"));
w.Timeout=TimeSpan.FromSeconds(100000);
w.UploadFile(c.GetStr("url"),"PUT",c.GetStr("file"));
}
}
catch (WebException e)
{
if (e.Response!=null)
try {
XS.XmlDoc xs=new XS.XmlDoc(((HttpWebResponse)e.Response).GetResponseStream());
c.Error.WriteLine("Error message: {0}",xs.V("/Error/Message/text()"));
}
catch
{
}
throw;
}
</code>
<print outTo="^info"> Done</print>
</foreach>
<?h using System.Security.Cryptography;
using System.Net;
public static class X
{
public static string FileMD5(string filename)
{
using (Stream fs=File.OpenRead(filename))
using (MD5 md5=MD5.Create())
return Convert.ToBase64String(md5.ComputeHash(fs),Base64FormattingOptions.None);
}
public static string SignUrl(string baseUrl, string accesskey, string secretkey, string directory, string filename,string md5)
{
directory=directory.TrimStart('/');
int n=directory.IndexOf('/');
string path=directory;
if (!path.EndsWith("/"))
path+='/';
path+=Path.GetFileName(filename);
string expiration=((long)((DateTime.UtcNow.AddDays(1)-new DateTime(1970, 1, 1)).TotalSeconds)).ToString();
using (HMACSHA1 sign = new HMACSHA1(Encoding.UTF8.GetBytes(secretkey)))
{
string escaped=Uri.EscapeUriString(path);
string stringToSign = string.Format("PUT\n{0}\napplication/octet-stream\n{1}\n/{2}",md5,expiration,escaped);
string authorization = Uri.EscapeDataString(Convert.ToBase64String(sign.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)),Base64FormattingOptions.None).Trim());
return string.Format( "{0}/{1}?AWSAccessKeyId={2}&Expires={3}&Signature={4}",baseUrl, escaped,accesskey,expiration,authorization);
}
}
}
?>
</xsharper>