-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: support get and set of exception fields
- Loading branch information
Showing
40 changed files
with
3,132 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,277 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Globalization; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace Tea.Streams | ||
{ | ||
public class FileField | ||
{ | ||
[NameInMap("filename")] | ||
public string Filename { get; set; } | ||
|
||
[NameInMap("contentType")] | ||
public string ContentType { get; set; } | ||
|
||
[NameInMap("content")] | ||
public Stream Content { get; set; } | ||
} | ||
|
||
public class FileFormStream : Stream | ||
{ | ||
|
||
private Stream streamingStream { get; set; } | ||
|
||
private Dictionary<string, object> form { get; set; } | ||
|
||
private string boundary; | ||
|
||
private List<string> keys; | ||
|
||
private int index; | ||
|
||
private bool streaming; | ||
|
||
private long position; | ||
|
||
private long length; | ||
|
||
public FileFormStream(Dictionary<string, object> form, string boundary) | ||
{ | ||
this.form = form; | ||
this.boundary = boundary; | ||
index = 0; | ||
keys = form.Keys.ToList(); | ||
streaming = false; | ||
} | ||
|
||
public override bool CanRead { get { return true; } } | ||
|
||
public override bool CanSeek { get { return false; } } | ||
|
||
public override bool CanWrite { get { return false; } } | ||
|
||
public override long Length { get { return length; } } | ||
|
||
public override long Position | ||
{ | ||
get | ||
{ | ||
return position; | ||
} | ||
set | ||
{ | ||
position = value; | ||
} | ||
} | ||
|
||
public override void Flush() | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
|
||
public override int Read(byte[] buffer, int offset, int count) | ||
{ | ||
if (streaming) | ||
{ | ||
int bytesRLength; | ||
if (streamingStream != null && (bytesRLength = streamingStream.Read(buffer, 0, buffer.Length)) != 0) | ||
{ | ||
return bytesRLength; | ||
} | ||
else | ||
{ | ||
streaming = false; | ||
if (streamingStream != null && streamingStream.CanSeek) | ||
{ | ||
streamingStream.Seek(0, SeekOrigin.Begin); | ||
} | ||
streamingStream = null; | ||
byte[] bytesFileEnd = Encoding.UTF8.GetBytes("\r\n"); | ||
for (int i = 0; i < bytesFileEnd.Length; i++) | ||
{ | ||
buffer[i] = bytesFileEnd[i]; | ||
} | ||
index++; | ||
return bytesFileEnd.Length; | ||
} | ||
} | ||
|
||
if (index < keys.Count) | ||
{ | ||
string name = this.keys[this.index]; | ||
object fieldValue = form[name]; | ||
if (fieldValue is FileField) | ||
{ | ||
FileField fileField = (FileField) fieldValue; | ||
|
||
streaming = true; | ||
streamingStream = fileField.Content; | ||
StringBuilder stringBuilder = new StringBuilder(); | ||
stringBuilder.Append("--").Append(boundary).Append("\r\n"); | ||
stringBuilder.Append("Content-Disposition: form-data; name=\"").Append(name).Append("\"; filename=\"").Append(fileField.Filename).Append("\"\r\n"); | ||
stringBuilder.Append("Content-Type: ").Append(fileField.ContentType).Append("\r\n\r\n"); | ||
byte[] startBytes = Encoding.UTF8.GetBytes(stringBuilder.ToString()); | ||
for (int i = 0; i < startBytes.Length; i++) | ||
{ | ||
buffer[i] = startBytes[i]; | ||
} | ||
return startBytes.Length; | ||
} | ||
else | ||
{ | ||
StringBuilder stringBuilder = new StringBuilder(); | ||
stringBuilder.Append("--").Append(boundary).Append("\r\n"); | ||
stringBuilder.Append("Content-Disposition: form-data; name=\"").Append(name).Append("\"\r\n\r\n"); | ||
stringBuilder.Append(fieldValue.ToString()).Append("\r\n"); | ||
byte[] formBytes = Encoding.UTF8.GetBytes(stringBuilder.ToString()); | ||
for (int i = 0; i < formBytes.Length; i++) | ||
{ | ||
buffer[i] = formBytes[i]; | ||
} | ||
index++; | ||
return formBytes.Length; | ||
} | ||
} | ||
else if (index == keys.Count) | ||
{ | ||
string endStr = string.Format("--{0}--\r\n", boundary); | ||
byte[] endBytes = Encoding.UTF8.GetBytes(endStr); | ||
for (int i = 0; i < endBytes.Length; i++) | ||
{ | ||
buffer[i] = endBytes[i]; | ||
} | ||
index++; | ||
return endBytes.Length; | ||
} | ||
else | ||
{ | ||
return 0; | ||
} | ||
} | ||
|
||
public new async Task<int> ReadAsync(byte[] buffer, int offset, int count) | ||
{ | ||
if (streaming) | ||
{ | ||
int bytesRLength; | ||
if (streamingStream != null && (bytesRLength = await streamingStream.ReadAsync(buffer, 0, buffer.Length)) != 0) | ||
{ | ||
return bytesRLength; | ||
} | ||
else | ||
{ | ||
streaming = false; | ||
if (streamingStream != null) | ||
{ | ||
streamingStream.Flush(); | ||
streamingStream.Close(); | ||
} | ||
streamingStream = null; | ||
byte[] bytesFileEnd = Encoding.UTF8.GetBytes("\r\n"); | ||
for (int i = 0; i < bytesFileEnd.Length; i++) | ||
{ | ||
buffer[i] = bytesFileEnd[i]; | ||
} | ||
index++; | ||
return bytesFileEnd.Length; | ||
} | ||
} | ||
|
||
if (index < keys.Count) | ||
{ | ||
string name = this.keys[this.index]; | ||
object fieldValue = form[name]; | ||
if (fieldValue is FileField) | ||
{ | ||
FileField fileField = (FileField) fieldValue; | ||
|
||
streaming = true; | ||
streamingStream = fileField.Content; | ||
StringBuilder stringBuilder = new StringBuilder(); | ||
stringBuilder.Append("--").Append(boundary).Append("\r\n"); | ||
stringBuilder.Append("Content-Disposition: form-data; name=\"").Append(name).Append("\"; filename=\"").Append(fileField.Filename).Append("\"\r\n"); | ||
stringBuilder.Append("Content-Type: ").Append(fileField.ContentType).Append("\r\n\r\n"); | ||
byte[] startBytes = Encoding.UTF8.GetBytes(stringBuilder.ToString()); | ||
for (int i = 0; i < startBytes.Length; i++) | ||
{ | ||
buffer[i] = startBytes[i]; | ||
} | ||
return startBytes.Length; | ||
} | ||
else | ||
{ | ||
StringBuilder stringBuilder = new StringBuilder(); | ||
stringBuilder.Append("--").Append(boundary).Append("\r\n"); | ||
stringBuilder.Append("Content-Disposition: form-data; name=\"").Append(name).Append("\"\r\n\r\n"); | ||
stringBuilder.Append(fieldValue.ToString()).Append("\r\n"); | ||
byte[] formBytes = Encoding.UTF8.GetBytes(stringBuilder.ToString()); | ||
for (int i = 0; i < formBytes.Length; i++) | ||
{ | ||
buffer[i] = formBytes[i]; | ||
} | ||
index++; | ||
return formBytes.Length; | ||
} | ||
} | ||
else if (index == keys.Count) | ||
{ | ||
string endStr = string.Format("--{0}--\r\n", boundary); | ||
byte[] endBytes = Encoding.UTF8.GetBytes(endStr); | ||
for (int i = 0; i < endBytes.Length; i++) | ||
{ | ||
buffer[i] = endBytes[i]; | ||
} | ||
index++; | ||
return endBytes.Length; | ||
} | ||
else | ||
{ | ||
return 0; | ||
} | ||
} | ||
|
||
public override long Seek(long offset, SeekOrigin origin) | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
|
||
public override void SetLength(long value) | ||
{ | ||
length = value; | ||
} | ||
|
||
public override void Write(byte[] buffer, int offset, int count) | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
|
||
internal static string PercentEncode(string value) | ||
{ | ||
if (value == null) | ||
{ | ||
return null; | ||
} | ||
var stringBuilder = new StringBuilder(); | ||
var text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~"; | ||
var bytes = Encoding.UTF8.GetBytes(value); | ||
foreach (char c in bytes) | ||
{ | ||
if (text.IndexOf(c) >= 0) | ||
{ | ||
stringBuilder.Append(c); | ||
} | ||
else | ||
{ | ||
stringBuilder.Append("%").Append(string.Format(CultureInfo.InvariantCulture, "{0:X2}", (int) c)); | ||
} | ||
} | ||
|
||
return stringBuilder.ToString().Replace("+", "%20") | ||
.Replace("*", "%2A").Replace("%7E", "~"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace Tea | ||
{ | ||
public class TeaArray | ||
{ | ||
public static int Unshift<T>(List<T> array, T data) | ||
{ | ||
array.Insert(0, data); | ||
return array.Count; | ||
} | ||
|
||
|
||
public static int Push<T>(List<T> array, T data) | ||
{ | ||
array.Add(data); | ||
return array.Count; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
using System.Text; | ||
|
||
namespace Tea | ||
{ | ||
public class TeaBytes | ||
{ | ||
public static byte[] From(string data, string type) | ||
{ | ||
string lowerEncoding = type.ToLower(); | ||
switch (lowerEncoding.ToLowerInvariant()) | ||
{ | ||
case "ascii": | ||
return Encoding.ASCII.GetBytes(data); | ||
case "bigendianunicode": | ||
return Encoding.BigEndianUnicode.GetBytes(data); | ||
case "unicode": | ||
return Encoding.Unicode.GetBytes(data); | ||
case "utf32": | ||
case "utf-32": | ||
return Encoding.UTF32.GetBytes(data); | ||
case "utf8": | ||
case "utf-8": | ||
return Encoding.UTF8.GetBytes(data); | ||
default: | ||
return Encoding.UTF8.GetBytes(data); | ||
} | ||
} | ||
|
||
public static string ToHex(byte[] raw) | ||
{ | ||
if (raw == null) | ||
{ | ||
return string.Empty; | ||
} | ||
|
||
StringBuilder result = new StringBuilder(raw.Length * 2); | ||
for (int i = 0; i < raw.Length; i++) | ||
result.Append(raw[i].ToString("x2")); | ||
return result.ToString(); | ||
} | ||
} | ||
} |
Oops, something went wrong.