/// <summary> /// Processes the request. /// </summary> /// <param name="context">The HttpContext for the incoming HTTP request.</param> /// <param name="statusCode">The HTTP Status Code that must be returned to the client.</param> /// <returns>The response that must be sent to the client.</returns> public override string ProcessRequest(HttpContext context, out HttpStatusCode statusCode) { if (!AtomPubHelper.ValidatePrecondition(context, base.BaseUri, out statusCode)) { if (HttpStatusCode.PreconditionFailed == statusCode) { return(Properties.Resources.ATOMPUB_PRECONDITION_FAILED); } else { return(Properties.Resources.ATOMPUB_RESOURCE_NOT_MODIFIED); } } string errorMessage = string.Empty; // used to hold updated member metadata. AtomEntryDocument atomDocument = null; AtomPubRequestType requestType = AtomPubHelper.GetAtomPubRequestType(context, base.BaseUri); try { switch (requestType) { case AtomPubRequestType.EditMember: atomDocument = UpdateMember(context); break; case AtomPubRequestType.EditMedia: atomDocument = UpdateMedia(context); break; case AtomPubRequestType.ServiceDocument: case AtomPubRequestType.Collection: case AtomPubRequestType.CollectionWithPageNo: case AtomPubRequestType.Unknwon: default: statusCode = HttpStatusCode.BadRequest; errorMessage = Resources.ATOMPUB_INVALID_URL; break; } } catch (ResourceNotFoundException) { statusCode = HttpStatusCode.NotFound; return(Properties.Resources.ATOMPUB_RESOURCE_NOT_FOUND); } if (null != atomDocument) { statusCode = HttpStatusCode.OK; string memberId = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.Id); string eTag = AtomPubHelper.CalculateETag(memberId); context.Response.AddHeader(AtomPubConstants.KeyETag, eTag); return(atomDocument.AtomEntry); } else { return(errorMessage); } }
/// <summary> /// Deletes a media resource using the information present in the HttpContext. /// </summary> /// <param name="context">The HttpContext for the incoming HTTP request.</param> /// <returns>True if the operation succeeds, False otherwise.</returns> private bool DeleteMedia(HttpContext context) { // Gets the atom request template match result to get requested collection name. string collectionName = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.CollectionName); string memberId = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.Id); IAtomPubStoreWriter atomPubStoreWriter = AtomPubStoreFactory.GetAtomPubStoreWriter(base.BaseUri.OriginalString); return(atomPubStoreWriter.DeleteMedia(collectionName, memberId)); }
/// <summary> /// Creates a member resource using the information present in the HttpContext. /// </summary> /// <param name="context">The HttpContext for the incoming HTTP request.</param> /// <returns>An AtomEntryDocument corresponding to the newly created member resource.</returns> private AtomEntryDocument CreateMember(HttpContext context) { string collectionName = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.CollectionName); //Get AtomEntryDocument for request to update the member information. AtomEntryDocument atomEntry = new AtomEntryDocument(context.Request.InputStream); IAtomPubStoreWriter atomPubStoreWriter = AtomPubStoreFactory.GetAtomPubStoreWriter(base.BaseUri.OriginalString); SyndicationItem item = atomPubStoreWriter.CreateMember(collectionName, atomEntry); // Create atom entry document from syndication item. return(new AtomEntryDocument(item)); }
/// <summary> /// Updates a member resource using the information present in the HttpContext. /// </summary> /// <param name="context">The HttpContext for the incoming HTTP request.</param> /// <returns>An AtomEntryDocument corresponding to the updated member resource.</returns> private AtomEntryDocument UpdateMember(HttpContext context) { // Gets the atom request template match result to get requested collection name. string collectionName = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.CollectionName); string memberId = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.Id); IAtomPubStoreWriter atomPubStoreWriter = AtomPubStoreFactory.GetAtomPubStoreWriter(base.BaseUri.OriginalString); //Get AtomEntryDocument for request to update the member information. AtomEntryDocument atomDocument = new AtomEntryDocument(context.Request.InputStream); SyndicationItem item = atomPubStoreWriter.UpdateMemberInfo(collectionName, memberId, atomDocument); // Get AtomEntryDocument for response. return(new AtomEntryDocument(item)); }
/// <summary> /// Validates the incoming request. /// </summary> /// <param name="context">The HttpContext for the incoming HTTP request.</param> /// <param name="errorMessage">The HTTP Status Code if the request is invalid.</param> /// <returns>True if the request is valid, False otherwise.</returns> public override bool ValidateRequest(HttpContext context, out string errorMessage) { // Verify that type of request is edit member or edit media request. AtomPubRequestType requestType = AtomPubHelper.GetAtomPubRequestType(context, base.BaseUri); if (!(AtomPubRequestType.EditMember == requestType || AtomPubRequestType.EditMedia == requestType)) { errorMessage = Resources.ATOMPUB_INVALID_URL; return(false); } bool isAtomEntryType = AtomPubHelper.IsAtomEntryMediaType(context.Request.ContentType); if (requestType == AtomPubRequestType.EditMember && !isAtomEntryType) { errorMessage = Resources.ATOMPUB_UNSUPPORTED_CONTENT_TYPE; return(false); } // Get the requested member type and its id for verifying it existents. string collectionName = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.CollectionName); if (!string.IsNullOrEmpty(collectionName) && AtomPubHelper.IsValidCollectionType(collectionName)) { string memberId = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.Id); if (!string.IsNullOrEmpty(memberId) && AtomPubHelper.IsValidGuid(memberId)) { errorMessage = string.Empty; return(true); } else { errorMessage = Resources.ATOMPUB_INVALID_RESOURCE_ID; return(false); } } else { errorMessage = Resources.ATOMPUB_UNSUPPORTED_COLLECTION_NAME; return(false); } }
/// <summary> /// Updates a media resource using the information present in the HttpContext. /// </summary> /// <param name="context">The HttpContext for the incoming HTTP request.</param> /// <returns>An AtomEntryDocument corresponding to the updated media resource.</returns> private AtomEntryDocument UpdateMedia(HttpContext context) { // Gets the atom request template match result to get requested collection name. string collectionName = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.CollectionName); string memberId = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.Id); IAtomPubStoreWriter atomPubStoreWriter = AtomPubStoreFactory.GetAtomPubStoreWriter(base.BaseUri.OriginalString); // Get byte array to update media. BinaryReader reader = new BinaryReader(context.Request.InputStream); byte[] media = new byte[context.Request.InputStream.Length]; reader.Read(media, 0, media.Length); SyndicationItem item = atomPubStoreWriter.UpdateMedia(collectionName, memberId, context.Request.ContentType, media); // Get AtomEntryDocument for response. return(new AtomEntryDocument(item)); }
/// <summary> /// Creates a media resource using the information present in the HttpContext. /// </summary> /// <param name="context">The HttpContext for the incoming HTTP request.</param> /// <returns>An AtomEntryDocument corresponding to the newly created media resource.</returns> private AtomEntryDocument CreateMedia(HttpContext context) { SyndicationItem item = null; string collectionName = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.CollectionName); // Get byte array to update media. BinaryReader reader = new BinaryReader(context.Request.InputStream); byte[] media = new byte[context.Request.InputStream.Length]; reader.Read(media, 0, media.Length); string fileExtention = string.Empty; if (context.Request.Headers.AllKeys.Contains("Content-Disposition")) { fileExtention = AtomPubHelper.GetFileExtentionFromContentDisposition( context.Request.Headers["Content-Disposition"]); } IAtomPubStoreWriter swordStoreWriter = AtomPubStoreFactory.GetSwordStoreWriter(); item = swordStoreWriter.CreateMedia(collectionName, context.Request.ContentType, media, fileExtention); AtomEntryDocument atomEntryDocument = null; if (null != item) { // Add <sword:treatment>Successfully created a {Collection Name}</sword:treatment> element. SwordPostProcessor.AddTreatmentElement(collectionName, item); // Create atom entry document from syndication item. atomEntryDocument = new AtomEntryDocument(item); } return(atomEntryDocument); }
/// <summary> /// Validates the request uri and returns the appropriate error message. /// If the request is valid, 'error' with empty string is returned. /// </summary> /// <param name="context">HttpContext containing the request object.</param> /// <param name="errorMessage">Contains the error message.</param> /// <returns>True if the request is valid, else false.</returns> public override bool ValidateRequest(HttpContext context, out string errorMessage) { bool isValid = false; AtomPubRequestType requestType = AtomPubHelper.GetAtomPubRequestType(context, base.BaseUri); switch (requestType) { case AtomPubRequestType.Collection: // Get collection name string collectionName = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.CollectionName); // If valid collection name, then proceed. if (!string.IsNullOrEmpty(collectionName) && AtomPubHelper.IsValidCollectionType(collectionName)) { errorMessage = string.Empty; isValid = true; } else { errorMessage = Properties.Resources.ATOMPUB_UNSUPPORTED_COLLECTION_NAME; isValid = false; } break; case AtomPubRequestType.Unknwon: default: errorMessage = Properties.Resources.ATOMPUB_INVALID_URL; isValid = false; break; } return(isValid); }
/// <summary> /// Creates a media resource using the information present in the HttpContext. /// </summary> /// <param name="context">The HttpContext for the incoming HTTP request.</param> /// <returns>An AtomEntryDocument corresponding to the newly created media resource.</returns> private AtomEntryDocument CreateMedia(HttpContext context) { string collectionName = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.CollectionName); string fileExtention = string.Empty; if (context.Request.Headers.AllKeys.Contains("Content-Disposition")) { fileExtention = AtomPubHelper.GetFileExtentionFromContentDisposition( context.Request.Headers["Content-Disposition"]); } // Get byte array to update media. BinaryReader reader = new BinaryReader(context.Request.InputStream); byte[] media = new byte[context.Request.InputStream.Length]; reader.Read(media, 0, media.Length); IAtomPubStoreWriter atomPubStoreWriter = AtomPubStoreFactory.GetAtomPubStoreWriter(base.BaseUri.OriginalString); SyndicationItem item = atomPubStoreWriter.CreateMedia(collectionName, context.Request.ContentType, media, fileExtention); // Create atom entry document from syndication item. return(new AtomEntryDocument(item)); }
/// <summary> /// Validates the request uri and returns the appropriate error message. /// If the request is valid, 'error' with empty string is returned. /// Following requests are considered as valid : /// 1. Service Document Uri /// 2. Collection Uri /// 3. Collection Uri for next / previous page /// 4. Member resource Uri /// 5. Media Entry resource Uri /// </summary> /// <param name="context">HttpContext containing the request object.</param> /// <param name="errorMessage">Contains the error message.</param> /// <returns>True if the request is valid, else false.</returns> public override bool ValidateRequest(HttpContext context, out string errorMessage) { errorMessage = string.Empty; AtomPubRequestType requestType = AtomPubHelper.GetAtomPubRequestType(context, base.BaseUri); if (AtomPubRequestType.Unknwon == requestType) { errorMessage = Resources.ATOMPUB_INVALID_URL; return(false); } // If ServiceDocument uri then no need of further validations. if (AtomPubRequestType.ServiceDocument == requestType) { return(true); } // Get collection name string collectionName = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.CollectionName); bool isValid = false; // If valid collection name, then proceed. if (!string.IsNullOrEmpty(collectionName) && AtomPubHelper.IsValidCollectionType(collectionName)) { switch (requestType) { case AtomPubRequestType.Collection: isValid = true; break; case AtomPubRequestType.CollectionWithPageNo: string strPageNo = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.PageNo); long pageNumber = 0; if (!long.TryParse(strPageNo, out pageNumber)) { errorMessage = Resources.ATOMPUB_INVALID_PAGE_NUMBER; } else { isValid = true; } break; case AtomPubRequestType.EditMember: case AtomPubRequestType.EditMedia: // Get the requested id for verify it is GUID string memberId = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.Id); if (AtomPubHelper.IsValidGuid(memberId)) { isValid = true; } else { errorMessage = Resources.ATOMPUB_INVALID_RESOURCE_ID; } break; default: isValid = false; errorMessage = Resources.ATOMPUB_INVALID_URL; break; } } else { errorMessage = Resources.ATOMPUB_UNSUPPORTED_COLLECTION_NAME; } return(isValid); }
/// <summary> /// Handles the GET request send to the following uri: /// 1. Service Document Uri /// 2. Collection Uri /// 3. Collection Uri for next / previous page /// 4. Member resource Uri /// 5. Media Entry resource Uri /// The method assumes that the request is already validated using ValidateRequest method. /// </summary> /// <param name="context">HttpContext containing the request object.</param> /// <param name="statusCode">returns the status of the request.</param> /// <returns>A string containing the response for the specified AtomPub request.</returns> public override string ProcessRequest(HttpContext context, out System.Net.HttpStatusCode statusCode) { string response = string.Empty; AtomPubRequestType requestType = AtomPubHelper.GetAtomPubRequestType(context, base.BaseUri); // Get collection name string collectionName = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.CollectionName); statusCode = HttpStatusCode.OK; // This assumes that the collection name is verified by ValidateRequest method. switch (requestType) { case AtomPubRequestType.ServiceDocument: response = this.GetServiceDocument(context); context.Response.ContentType = AtomPubConstants.ServiceDocumentContentType; break; case AtomPubRequestType.Collection: response = this.GetAtomFeed(collectionName); break; case AtomPubRequestType.CollectionWithPageNo: string strPageNo = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.PageNo); long pageNumber = long.Parse(strPageNo, CultureInfo.InvariantCulture); response = this.GetAtomFeed(collectionName, pageNumber); context.Response.ContentType = AtomPubConstants.AtomFeedContentType; break; case AtomPubRequestType.EditMember: { // Get the requested member type and its id for verifying it existents. string memberId = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.Id); try { if (AtomPubHelper.ValidatePrecondition(context, base.BaseUri, out statusCode)) { string eTag = AtomPubHelper.CalculateETag(memberId); context.Response.AddHeader(AtomPubConstants.KeyETag, eTag); response = this.GetAtomEntryDocument(collectionName, memberId).AtomEntry; context.Response.ContentType = AtomPubConstants.AtomEntryContentType; statusCode = HttpStatusCode.OK; } else { if (HttpStatusCode.PreconditionFailed == statusCode) { response = Properties.Resources.ATOMPUB_PRECONDITION_FAILED; } else { response = Properties.Resources.ATOMPUB_RESOURCE_NOT_MODIFIED; } } } catch (ResourceNotFoundException) { statusCode = HttpStatusCode.NotFound; response = Properties.Resources.ATOMPUB_RESOURCE_NOT_FOUND; } } break; case AtomPubRequestType.EditMedia: { // Get the requested member type and its id for verifying it existents. string memberId = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.Id); try { if (AtomPubHelper.ValidatePrecondition(context, base.BaseUri, out statusCode)) { //context.Response.Clear(); string eTag = AtomPubHelper.CalculateETag(memberId); context.Response.AddHeader(AtomPubConstants.KeyETag, eTag); byte[] content = null; // Write the media contents on stream. this.GetMediaResource(collectionName, memberId, out content); context.Response.OutputStream.Write(content, 0, content.Length); string fileExtension = string.Empty; context.Response.ContentType = GetMediaContentType(collectionName, memberId, out fileExtension); string attachedFileName = string.Format(CultureInfo.InvariantCulture, "attachment; filename={0}.{1}", memberId, fileExtension); context.Response.AddHeader("Content-Disposition", attachedFileName); context.Response.AddHeader("Content-Length", content.Length.ToString(CultureInfo.InvariantCulture)); statusCode = HttpStatusCode.OK; } else { if (HttpStatusCode.PreconditionFailed == statusCode) { response = Properties.Resources.ATOMPUB_PRECONDITION_FAILED; } else { response = Properties.Resources.ATOMPUB_RESOURCE_NOT_MODIFIED; } } } catch (ResourceNotFoundException) { statusCode = HttpStatusCode.NotFound; response = Properties.Resources.ATOMPUB_RESOURCE_NOT_FOUND; } } break; case AtomPubRequestType.Unknwon: default: statusCode = HttpStatusCode.BadRequest; response = Properties.Resources.ATOMPUB_BAD_REQUEST; break; } return(response); }
/// <summary> /// Handles the POST request send to the collection Uri. The method assumes that the request is /// already validated using ValidateRequest method. /// </summary> /// <param name="context">HttpContext containing the request.</param> /// <param name="statusCode">Contains the status of the request.</param> /// <returns>A string containing the response for the specified AtomPub request.</returns> /// <remarks>If a zip file is sent with the POST request to the collection uri, /// the contents of the zip file are extracted and the individual files will be uploaded /// in the repository. /// The zip file should contain the mets.xml containing the metadata of the individual files. /// If mets.xml is not found in the specified zip file, status code 'PreconditionFailed' will /// be returned. /// </remarks> public override string ProcessRequest(HttpContext context, out System.Net.HttpStatusCode statusCode) { string response = string.Empty; AtomEntryDocument atomEntryDocument = null; bool isAtomEntryType = AtomPubHelper.IsAtomEntryMediaType(context.Request.ContentType); try { if (isAtomEntryType) { response = base.ProcessRequest(context, out statusCode); System.Xml.XmlTextReader responseReader = null; try { responseReader = new System.Xml.XmlTextReader(response, System.Xml.XmlNodeType.Document, null); SyndicationItem responseItem = SyndicationItem.Load(responseReader); string collectionName = AtomPubHelper.GetValueOfParameterFromUri(context, base.BaseUri, AtomPubParameterType.CollectionName); // Add <sword:treatment>Successfully created a {Collection Name}</sword:treatment> element. SwordPostProcessor.AddTreatmentElement(collectionName, responseItem); // Create atom entry document from syndication item. atomEntryDocument = new AtomEntryDocument(responseItem); } finally { responseReader.Close(); } context.Response.ContentType = AtomPubConstants.AtomEntryContentType; } else { // If request stream contains something other than AtomEntryDocument, // then client wants to create new member with Media. atomEntryDocument = this.CreateMedia(context); // Done this separately because if AtomEntry is null due to some reasons, // then also it will set the content type. context.Response.ContentType = AtomPubConstants.AtomEntryContentType; } // return the atom entry response. if (null != atomEntryDocument) { response = atomEntryDocument.AtomEntry; statusCode = System.Net.HttpStatusCode.Created; } else { statusCode = System.Net.HttpStatusCode.InternalServerError; } } catch (MetsException ex) { statusCode = System.Net.HttpStatusCode.InternalServerError; response = ex.Message; } catch (SwordException ex) { statusCode = System.Net.HttpStatusCode.UnsupportedMediaType; response = ex.Message; } finally { string zipExtractedPath = context.Items[SwordConstants.ZipExtractedPath] as string; if (!string.IsNullOrEmpty(zipExtractedPath) && Directory.Exists(zipExtractedPath)) { Directory.Delete(zipExtractedPath, true); context.Items[SwordConstants.ZipExtractedPath] = null; } } return(response); }