/// <summary> /// Attach a file to a JIRA issue (bug). /// <seealso cref="https://docs.atlassian.com/jira/REST/latest/#idp1726000"/> /// </summary> /// <param name="issueKey">THe key of the bug to attach the file to e.g. TSCB-14.</param> /// <param name="attachment">The declaration of the file to be attached.</param> /// <returns>A FileAttached object.</returns> internal static JiraFileAttached AttachFile(string server, string user, Base64String password, string issueKey, IBugAttachment attachment, out string error) { JiraFileAttached fileAttached = new JiraFileAttached(); string boundaryMarker = "-------------------------" + DateTime.Now.Ticks.ToString(); HttpWebRequest httpWebRequest = HttpWebRequest.Create(server + "/rest/api/2/issue/" + issueKey + "/attachments") as HttpWebRequest; httpWebRequest.Method = "POST"; httpWebRequest.UserAgent = agent; httpWebRequest.ContentType = "multipart/form-data; boundary=" + boundaryMarker; httpWebRequest.ProtocolVersion = HttpVersion.Version11; httpWebRequest.Headers.Add("X-Atlassian-Token: nocheck"); httpWebRequest.KeepAlive = true; httpWebRequest.Proxy = WebRequest.GetSystemWebProxy(); // Add the required authentication header if (!string.IsNullOrEmpty(user) && password.Length > 0) { Base64String authInfo = password.prefix(user + ":"); httpWebRequest.Headers["Authorization"] = "Basic " + authInfo; } FileInfo fi = new FileInfo(attachment.FileName); string contentHeader = "--" + boundaryMarker + "\r\n"; contentHeader += "Content-Disposition: form-data; name=\"file\"; filename=\"" + HttpUtility.HtmlEncode(fi.Name) + "\"\r\n"; contentHeader += "Content-Type: application/octet-stream\r\n"; //TODO If attaching something other than .zip files, this will have to change. contentHeader += "\r\n"; byte[] contentHeaderBytes = System.Text.Encoding.UTF8.GetBytes(contentHeader); try { FileStream fs = new FileStream(attachment.FileName, FileMode.Open, FileAccess.Read, FileShare.Read); byte[] requestBytes = new byte[65536]; int bytesRead = 0; using (Stream requestStream = httpWebRequest.GetRequestStream()) { requestStream.Write(contentHeaderBytes, 0, contentHeaderBytes.Length); while ((bytesRead = fs.Read(requestBytes, 0, requestBytes.Length)) != 0) { requestStream.Write(requestBytes, 0, bytesRead); } fs.Close(); string closingBoundary = "\r\n--" + boundaryMarker + "--"; byte[] closingBoundaryBytes = System.Text.Encoding.UTF8.GetBytes(closingBoundary); requestStream.Write(closingBoundaryBytes, 0, closingBoundaryBytes.Length); } } catch (FileNotFoundException e) { error = e.Message; return null; } //READ RESPONSE FROM STREAM try { using (JsonTextReader streamReader = new JsonTextReader(new StreamReader(httpWebRequest.GetResponse().GetResponseStream()))) { // JIRA supports attaching multiple files at once. Hence it returns an array of FileAttached objects. // Since we only attach one file at a time, we only need to parse the first one and return it. JArray result = (JArray)JArray.ReadFrom(streamReader); JsonConvert.PopulateObject(result[0].ToString(), fileAttached); } error = null; return fileAttached; } catch (WebException e) { error = e.Message; // Get the HTML response returned, if any //StreamReader rdr = new StreamReader(e.Response.GetResponseStream()); //string response = rdr.ReadToEnd(); return null; } }
/// <summary> /// Attach a file to a JIRA issue (bug). /// <seealso cref="https://docs.atlassian.com/jira/REST/latest/#idp1726000"/> /// </summary> /// <param name="issueKey">THe key of the bug to attach the file to e.g. TSCB-14.</param> /// <param name="attachment">The declaration of the file to be attached.</param> /// <returns>A FileAttached object.</returns> internal static JiraFileAttached AttachFile(string server, string user, Base64String password, string issueKey, IBugAttachment attachment, out string error) { JiraFileAttached fileAttached = new JiraFileAttached(); string boundaryMarker = "-------------------------" + DateTime.Now.Ticks.ToString(); HttpWebRequest httpWebRequest = HttpWebRequest.Create(server + "/rest/api/2/issue/" + issueKey + "/attachments") as HttpWebRequest; httpWebRequest.Method = "POST"; httpWebRequest.UserAgent = agent; httpWebRequest.ContentType = "multipart/form-data; boundary=" + boundaryMarker; httpWebRequest.ProtocolVersion = HttpVersion.Version11; httpWebRequest.Headers.Add("X-Atlassian-Token: nocheck"); httpWebRequest.KeepAlive = true; httpWebRequest.Proxy = WebRequest.GetSystemWebProxy(); // Add the required authentication header if (!string.IsNullOrEmpty(user) && password.Length > 0) { Base64String authInfo = password.prefix(user + ":"); httpWebRequest.Headers["Authorization"] = "Basic " + authInfo; } FileInfo fi = new FileInfo(attachment.FileName); string contentHeader = "--" + boundaryMarker + "\r\n"; contentHeader += "Content-Disposition: form-data; name=\"file\"; filename=\"" + HttpUtility.HtmlEncode(fi.Name) + "\"\r\n"; contentHeader += "Content-Type: application/octet-stream\r\n"; //TODO If attaching something other than .zip files, this will have to change. contentHeader += "\r\n"; byte[] contentHeaderBytes = System.Text.Encoding.UTF8.GetBytes(contentHeader); try { FileStream fs = new FileStream(attachment.FileName, FileMode.Open, FileAccess.Read, FileShare.Read); byte[] requestBytes = new byte[65536]; int bytesRead = 0; using (Stream requestStream = httpWebRequest.GetRequestStream()) { requestStream.Write(contentHeaderBytes, 0, contentHeaderBytes.Length); while ((bytesRead = fs.Read(requestBytes, 0, requestBytes.Length)) != 0) { requestStream.Write(requestBytes, 0, bytesRead); } fs.Close(); string closingBoundary = "\r\n--" + boundaryMarker + "--"; byte[] closingBoundaryBytes = System.Text.Encoding.UTF8.GetBytes(closingBoundary); requestStream.Write(closingBoundaryBytes, 0, closingBoundaryBytes.Length); } } catch (FileNotFoundException e) { error = e.Message; return(null); } //READ RESPONSE FROM STREAM try { using (JsonTextReader streamReader = new JsonTextReader(new StreamReader(httpWebRequest.GetResponse().GetResponseStream()))) { // JIRA supports attaching multiple files at once. Hence it returns an array of FileAttached objects. // Since we only attach one file at a time, we only need to parse the first one and return it. JArray result = (JArray)JArray.ReadFrom(streamReader); JsonConvert.PopulateObject(result[0].ToString(), fileAttached); } error = null; return(fileAttached); } catch (WebException e) { error = e.Message; // Get the HTML response returned, if any //StreamReader rdr = new StreamReader(e.Response.GetResponseStream()); //string response = rdr.ReadToEnd(); return(null); } }